From 449e36f52e8441aee9b1825d3696bebfb3cdfcf7 Mon Sep 17 00:00:00 2001 From: Puja Jagani Date: Wed, 13 Nov 2024 10:35:40 +0530 Subject: [PATCH] [bidi][js] Allow passing in uri for authentication handlers (#14386) Co-authored-by: David Burns --- .../node/selenium-webdriver/lib/network.js | 53 ++++++++++++------- .../test/lib/webdriver_network_test.js | 40 +++++++++++++- 2 files changed, 72 insertions(+), 21 deletions(-) diff --git a/javascript/node/selenium-webdriver/lib/network.js b/javascript/node/selenium-webdriver/lib/network.js index 5ab24c4b0da9fe..1c55264653484a 100644 --- a/javascript/node/selenium-webdriver/lib/network.js +++ b/javascript/node/selenium-webdriver/lib/network.js @@ -20,9 +20,10 @@ const { InterceptPhase } = require('../bidi/interceptPhase') const { AddInterceptParameters } = require('../bidi/addInterceptParameters') class Network { + #callbackId = 0 #driver #network - #callBackInterceptIdMap = new Map() + #authHandlers = new Map() constructor(driver) { this.#driver = driver @@ -39,39 +40,51 @@ class Network { return } this.#network = await network(this.#driver) - } - async addAuthenticationHandler(username, password) { - await this.#init() + await this.#network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED)) - const interceptId = await this.#network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED)) + await this.#network.authRequired(async (event) => { + const requestId = event.request.request + const uri = event.request.url + const credentials = this.getAuthCredentials(uri) + if (credentials !== null) { + await this.#network.continueWithAuth(requestId, credentials.username, credentials.password) + return + } - const id = await this.#network.authRequired(async (event) => { - await this.#network.continueWithAuth(event.request.request, username, password) + await this.#network.continueWithAuthNoCredentials(requestId) }) + } + + getAuthCredentials(uri) { + for (let [, value] of this.#authHandlers) { + if (uri.match(value.uri)) { + return value + } + } + return null + } + async addAuthenticationHandler(username, password, uri = '//') { + await this.#init() - this.#callBackInterceptIdMap.set(id, interceptId) + const id = this.#callbackId++ + + this.#authHandlers.set(id, { username, password, uri }) return id } async removeAuthenticationHandler(id) { await this.#init() - const interceptId = this.#callBackInterceptIdMap.get(id) - - await this.#network.removeIntercept(interceptId) - await this.#network.removeCallback(id) - - this.#callBackInterceptIdMap.delete(id) + if (this.#authHandlers.has(id)) { + this.#authHandlers.delete(id) + } else { + throw Error(`Callback with id ${id} not found`) + } } async clearAuthenticationHandlers() { - for (const [key, value] of this.#callBackInterceptIdMap.entries()) { - await this.#network.removeIntercept(value) - await this.#network.removeCallback(key) - } - - this.#callBackInterceptIdMap.clear() + this.#authHandlers.clear() } } diff --git a/javascript/node/selenium-webdriver/test/lib/webdriver_network_test.js b/javascript/node/selenium-webdriver/test/lib/webdriver_network_test.js index 538fefa87916d7..ff1ce496bf0381 100644 --- a/javascript/node/selenium-webdriver/test/lib/webdriver_network_test.js +++ b/javascript/node/selenium-webdriver/test/lib/webdriver_network_test.js @@ -45,6 +45,35 @@ suite( assert.equal(source.includes('Access granted'), true) }) + it('can add authentication handler with filter', async function () { + await driver.network().addAuthenticationHandler('genie', 'bottle', 'basicAuth') + await driver.get(Pages.basicAuth) + + await driver.wait(until.elementLocated(By.css('pre'))) + let source = await driver.getPageSource() + assert.equal(source.includes('Access granted'), true) + }) + + it('can add multiple authentication handlers with filter', async function () { + await driver.network().addAuthenticationHandler('genie', 'bottle', 'basicAuth') + await driver.network().addAuthenticationHandler('test', 'test', 'test') + await driver.get(Pages.basicAuth) + + await driver.wait(until.elementLocated(By.css('pre'))) + let source = await driver.getPageSource() + assert.equal(source.includes('Access granted'), true) + }) + + it('can add multiple authentication handlers with the same filter', async function () { + await driver.network().addAuthenticationHandler('genie', 'bottle', 'basicAuth') + await driver.network().addAuthenticationHandler('genie', 'bottle', 'basicAuth') + await driver.get(Pages.basicAuth) + + await driver.wait(until.elementLocated(By.css('pre'))) + let source = await driver.getPageSource() + assert.equal(source.includes('Access granted'), true) + }) + it('can remove authentication handler', async function () { const id = await driver.network().addAuthenticationHandler('genie', 'bottle') @@ -59,8 +88,17 @@ suite( } }) + it('throws an error when remove authentication handler that does not exist', async function () { + try { + await driver.network().removeAuthenticationHandler(10) + assert.fail('Expected error not thrown. Non-existent handler cannot be removed') + } catch (e) { + assert.strictEqual(e.message, 'Callback with id 10 not found') + } + }) + it('can clear authentication handlers', async function () { - await driver.network().addAuthenticationHandler('genie', 'bottle') + await driver.network().addAuthenticationHandler('genie', 'bottle', 'basicAuth') await driver.network().addAuthenticationHandler('bottle', 'genie')