diff --git a/MODULE.bazel b/MODULE.bazel index ccf7f61befdfa..724f137f6f0b1 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -181,7 +181,7 @@ maven.install( "com.graphql-java:graphql-java:22.3", "dev.failsafe:failsafe:3.3.2", "io.grpc:grpc-context:1.69.0", - "io.lettuce:lettuce-core:6.5.1.RELEASE", + "io.lettuce:lettuce-core:6.5.2.RELEASE", "io.netty:netty-buffer", "io.netty:netty-codec-http", "io.netty:netty-codec-http2", @@ -201,10 +201,10 @@ maven.install( "io.opentelemetry.semconv:opentelemetry-semconv:1.28.0-alpha", "it.ozimov:embedded-redis:0.7.3", "net.bytebuddy:byte-buddy:1.15.11", - "org.htmlunit:htmlunit-core-js:4.6.0", + "org.htmlunit:htmlunit-core-js:4.7.0", "org.apache.commons:commons-exec:1.4.0", "org.apache.logging.log4j:log4j-core:2.24.3", - "org.assertj:assertj-core:3.27.1", + "org.assertj:assertj-core:3.27.2", "org.bouncycastle:bcpkix-jdk18on:1.79", "org.eclipse.mylyn.github:org.eclipse.egit.github.core:2.1.5", "org.hsqldb:hsqldb:2.7.4", diff --git a/common/src/web/fedcm/fedcm_async_js.html b/common/src/web/fedcm/fedcm_async_js.html new file mode 100644 index 0000000000000..d1411be0a4cec --- /dev/null +++ b/common/src/web/fedcm/fedcm_async_js.html @@ -0,0 +1,40 @@ + + + + FedCM Example + + + +
+ + + + \ No newline at end of file diff --git a/dotnet/src/webdriver/Remote/HttpCommandExecutor.cs b/dotnet/src/webdriver/Remote/HttpCommandExecutor.cs index 0686239405e38..85921d73954be 100644 --- a/dotnet/src/webdriver/Remote/HttpCommandExecutor.cs +++ b/dotnet/src/webdriver/Remote/HttpCommandExecutor.cs @@ -316,7 +316,7 @@ private async Task MakeHttpRequest(HttpRequestInfo requestInfo private Response CreateResponse(HttpResponseInfo responseInfo) { - Response response = new Response(); + Response response; string body = responseInfo.Body; if ((int)responseInfo.StatusCode < 200 || (int)responseInfo.StatusCode > 299) { @@ -326,8 +326,7 @@ private Response CreateResponse(HttpResponseInfo responseInfo) } else { - response.Status = WebDriverResult.UnknownError; - response.Value = body; + response = new Response(sessionId: null, body, WebDriverResult.UnknownError); } } else if (responseInfo.ContentType != null && responseInfo.ContentType.StartsWith(JsonMimeType, StringComparison.OrdinalIgnoreCase)) @@ -336,12 +335,12 @@ private Response CreateResponse(HttpResponseInfo responseInfo) } else { - response.Value = body; + response = new Response(sessionId: null, body, WebDriverResult.Success); } - if (response.Value is string) + if (response.Value is string valueString) { - response.Value = ((string)response.Value).Replace("\r\n", "\n").Replace("\n", Environment.NewLine); + response.Value = valueString.Replace("\r\n", "\n").Replace("\n", Environment.NewLine); } return response; diff --git a/dotnet/src/webdriver/Response.cs b/dotnet/src/webdriver/Response.cs index abe4bb2a9fcdd..9a0de908859a5 100644 --- a/dotnet/src/webdriver/Response.cs +++ b/dotnet/src/webdriver/Response.cs @@ -24,6 +24,8 @@ using System.Text.Json; using System.Text.Json.Serialization; +#nullable enable + namespace OpenQA.Selenium { /// @@ -48,12 +50,22 @@ public Response() /// Initializes a new instance of the class /// /// Session ID in use - public Response(SessionId sessionId) + public Response(SessionId? sessionId) { - if (sessionId != null) - { - this.SessionId = sessionId.ToString(); - } + this.SessionId = sessionId?.ToString(); + } + + /// + /// Initializes a new instance of the class + /// + /// The Session ID in use, if any. + /// The JSON payload of the response. + /// The WebDriver result status of the response. + public Response(string? sessionId, object? value, WebDriverResult status) + { + this.SessionId = sessionId; + this.Value = value; + this.Status = status; } /// @@ -61,75 +73,75 @@ public Response(SessionId sessionId) /// /// The JSON string to deserialize into a . /// A object described by the JSON string. + /// If is . + /// If is not a valid JSON object. public static Response FromJson(string value) { - Dictionary rawResponse = JsonSerializer.Deserialize>(value, s_jsonSerializerOptions) + Dictionary rawResponse = JsonSerializer.Deserialize>(value, s_jsonSerializerOptions) ?? throw new WebDriverException("JSON success response returned \"null\" value"); - var response = new Response(); + object? contents; + string? sessionId = null; - if (rawResponse.ContainsKey("sessionId")) + if (rawResponse.TryGetValue("sessionId", out object? s) && s is not null) { - if (rawResponse["sessionId"] != null) - { - response.SessionId = rawResponse["sessionId"].ToString(); - } + sessionId = s.ToString(); } - if (rawResponse.TryGetValue("value", out object valueObj)) + if (rawResponse.TryGetValue("value", out object? valueObj)) { - response.Value = valueObj; + contents = valueObj; } - - // If the returned object does *not* have a "value" property - // the response value should be the entirety of the response. - // TODO: Remove this if statement altogether; there should - // never be a spec-compliant response that does not contain a - // value property. - if (!rawResponse.ContainsKey("value") && response.Value == null) + else { + // If the returned object does *not* have a "value" property + // the response value should be the entirety of the response. + // TODO: Remove this if statement altogether; there should + // never be a spec-compliant response that does not contain a + // value property. + // Special-case for the new session command, where the "capabilities" // property of the response is the actual value we're interested in. - if (rawResponse.ContainsKey("capabilities")) + if (rawResponse.TryGetValue("capabilities", out object? capabilities)) { - response.Value = rawResponse["capabilities"]; + contents = capabilities; } else { - response.Value = rawResponse; + contents = rawResponse; } } - if (response.Value is Dictionary valueDictionary) + if (contents is Dictionary valueDictionary) { // Special case code for the new session command. If the response contains // sessionId and capabilities properties, fix up the session ID and value members. - if (valueDictionary.ContainsKey("sessionId")) + if (valueDictionary.TryGetValue("sessionId", out object? session)) { - response.SessionId = valueDictionary["sessionId"].ToString(); - if (valueDictionary.TryGetValue("capabilities", out object capabilities)) + sessionId = session.ToString(); + if (valueDictionary.TryGetValue("capabilities", out object? capabilities)) { - response.Value = capabilities; + contents = capabilities; } else { - response.Value = valueDictionary["value"]; + contents = valueDictionary["value"]; } } } - return response; + return new Response(sessionId, contents, WebDriverResult.Success); } /// /// Gets or sets the value from JSON. /// - public object Value { get; set; } + public object? Value { get; set; } /// /// Gets or sets the session ID. /// - public string SessionId { get; set; } + public string? SessionId { get; set; } /// /// Gets or sets the status value of the response. @@ -142,26 +154,25 @@ public static Response FromJson(string value) /// /// The JSON string to deserialize into a . /// A object described by the JSON string. + /// If is . + /// If is not a valid JSON object. + /// If the JSON dictionary is not in the expected state, per spec. public static Response FromErrorJson(string value) { - var deserializedResponse = JsonSerializer.Deserialize>(value, s_jsonSerializerOptions) + Dictionary deserializedResponse = JsonSerializer.Deserialize>(value, s_jsonSerializerOptions) ?? throw new WebDriverException("JSON error response returned \"null\" value"); - var response = new Response(); - - if (!deserializedResponse.TryGetValue("value", out var valueObject)) + if (!deserializedResponse.TryGetValue("value", out object? valueObject)) { throw new WebDriverException($"The 'value' property was not found in the response:{Environment.NewLine}{value}"); } - if (valueObject is not Dictionary valueDictionary) + if (valueObject is not Dictionary valueDictionary) { throw new WebDriverException($"The 'value' property is not a dictionary of {Environment.NewLine}{value}"); } - response.Value = valueDictionary; - - if (!valueDictionary.TryGetValue("error", out var errorObject)) + if (!valueDictionary.TryGetValue("error", out object? errorObject)) { throw new WebDriverException($"The 'value > error' property was not found in the response:{Environment.NewLine}{value}"); } @@ -171,11 +182,9 @@ public static Response FromErrorJson(string value) throw new WebDriverException($"The 'value > error' property is not a string{Environment.NewLine}{value}"); } - response.Value = deserializedResponse["value"]; - - response.Status = WebDriverError.ResultFromError(errorString); + WebDriverResult status = WebDriverError.ResultFromError(errorString); - return response; + return new Response(sessionId: null, valueDictionary, status); } /// diff --git a/java/maven_install.json b/java/maven_install.json index b21bf018ab565..4b6e999df0928 100644 --- a/java/maven_install.json +++ b/java/maven_install.json @@ -1,7 +1,7 @@ { "__AUTOGENERATED_FILE_DO_NOT_MODIFY_THIS_FILE_MANUALLY": "THERE_IS_NO_DATA_ONLY_ZUUL", - "__INPUT_ARTIFACTS_HASH": -1069673593, - "__RESOLVED_ARTIFACTS_HASH": -1004221368, + "__INPUT_ARTIFACTS_HASH": 1132645732, + "__RESOLVED_ARTIFACTS_HASH": 1947623231, "artifacts": { "com.beust:jcommander": { "shasums": { @@ -228,10 +228,10 @@ }, "io.lettuce:lettuce-core": { "shasums": { - "jar": "ff26c28351becdaf6d5abe25d97ea799a986b1746bfe5f70659d1e53745b6f1a", - "sources": "383337d6e56a97563c31f2d06838c85f8295662a5f7f72408bef5d59329cf98a" + "jar": "59f6a591a631d844b355b831ee723bf6ce98d92f7a775de6b0690f0eb81480e7", + "sources": "e9d835ed5b0583fbf01deabdb2c4ab370ac73166a4011aac5f1e2ca397914912" }, - "version": "6.5.1.RELEASE" + "version": "6.5.2.RELEASE" }, "io.netty:netty-buffer": { "shasums": { @@ -550,10 +550,10 @@ }, "org.assertj:assertj-core": { "shasums": { - "jar": "ab4ab885146bc5dfbdd4cdfb06f1ae72ec6b5e8139f0ccdabcbe51374aebac0d", - "sources": "0c9a7b4a85f3609bf700ad13f4173cde85cadcdd8feb829e059a000a5b9aa932" + "jar": "a8079b4cb67dca1dc5c7650bf27bd59277834c63280b661475986de3b602e3ae", + "sources": "fc96972d63cc234226a10b5a434acb085033f2bc68035df92abc3331595aa73d" }, - "version": "3.27.1" + "version": "3.27.2" }, "org.bouncycastle:bcpkix-jdk18on": { "shasums": { @@ -606,10 +606,10 @@ }, "org.htmlunit:htmlunit-core-js": { "shasums": { - "jar": "709c43eaab5b407468239b49ba990a7170ee582cbaa6a11c09a6118da22fdedc", - "sources": "458acacd14d851ad0ad20310787b35d3224d0c31155bd6b17d41de2b352bb1b7" + "jar": "4f0c609fbfd2ca2ca9163cc63e9b947b13a57b5644400e2b1902c1335d160888", + "sources": "5834536abb3402f859cbb31f48d113e36c2dc6bc7dd7e01eca6478a61d00c70c" }, - "version": "4.6.0" + "version": "4.7.0" }, "org.jodd:jodd-util": { "shasums": { diff --git a/java/src/org/openqa/selenium/Platform.java b/java/src/org/openqa/selenium/Platform.java index 66f7927eaeb9b..98d859b642689 100644 --- a/java/src/org/openqa/selenium/Platform.java +++ b/java/src/org/openqa/selenium/Platform.java @@ -32,7 +32,7 @@ public enum Platform { /** Never returned, but can be used to request a browser running on any version of Windows. */ - WINDOWS("") { + WINDOWS("windows") { @Override public Platform family() { return null; @@ -302,6 +302,18 @@ public String toString() { } }, + SEQUOIA("sequoia", "os x 15.0", "macos 15.0") { + @Override + public Platform family() { + return MAC; + } + + @Override + public String toString() { + return "macOS 15.0"; + } + }, + /** Many platforms have UNIX traits, amongst them LINUX, Solaris and BSD. */ UNIX("solaris", "bsd") { @Override diff --git a/java/test/org/openqa/selenium/PlatformTest.java b/java/test/org/openqa/selenium/PlatformTest.java index a87bc6bf0d9eb..8ff72882e0270 100644 --- a/java/test/org/openqa/selenium/PlatformTest.java +++ b/java/test/org/openqa/selenium/PlatformTest.java @@ -24,8 +24,10 @@ import static org.openqa.selenium.Platform.IOS; import static org.openqa.selenium.Platform.LINUX; import static org.openqa.selenium.Platform.MAC; +import static org.openqa.selenium.Platform.SEQUOIA; import static org.openqa.selenium.Platform.UNIX; import static org.openqa.selenium.Platform.VISTA; +import static org.openqa.selenium.Platform.WIN11; import static org.openqa.selenium.Platform.WIN8; import static org.openqa.selenium.Platform.WIN8_1; import static org.openqa.selenium.Platform.WINDOWS; @@ -57,6 +59,11 @@ void testWin81IsWindows() { assertThat(WIN8_1.is(WINDOWS)).isTrue(); } + @Test + void testWindows11IsWindows() { + assertThat(WIN11.is(WINDOWS)).isTrue(); + } + @Test void testLinuxIsUnix() { assertThat(LINUX.is(UNIX)).isTrue(); @@ -165,16 +172,41 @@ void testWindowsIsWindows() { assertThat(WINDOWS).isEqualTo(Platform.fromString("windows")); } + @Test + void testWindowsIsNotEmpty() { + assertThat(WINDOWS).isNotEqualTo(Platform.fromString("")); + } + @Test void canParseMacOsXCorrectly() { assertThat(Platform.fromString("Mac OS X")).isEqualTo(MAC); } + @Test + void testAnyIsFromStringEmpty() { + assertThat(ANY).isEqualTo(Platform.fromString("")); + } + + @Test + void testAnyIsFromStringAny() { + assertThat(ANY).isEqualTo(Platform.fromString("any")); + } + + @Test + void testAnyIsNotFromStringWindows() { + assertThat(ANY).isNotEqualTo(Platform.fromString("windows")); + } + @Test void catalinaIsMac() { assertThat(CATALINA.is(MAC)).isTrue(); } + @Test + void sequoiaIsMac() { + assertThat(SEQUOIA.is(MAC)).isTrue(); + } + @Test void canParseCatalinaFromOSName() { assertThat(Platform.fromString("macOS 10.15")).isEqualTo(CATALINA); diff --git a/javascript/grid-ui/package.json b/javascript/grid-ui/package.json index 2e7195ce1ab32..042029c165e3d 100644 --- a/javascript/grid-ui/package.json +++ b/javascript/grid-ui/package.json @@ -12,8 +12,8 @@ "@novnc/novnc": "1.5.0", "@types/jest": "29.5.14", "@types/node": "20.12.12", - "@types/react": "18.2.72", - "@types/react-dom": "18.2.22", + "@types/react": "18.3.18", + "@types/react-dom": "18.3.5", "@types/react-modal": "3.16.3", "@types/react-router-dom": "5.3.3", "graphql": "16.10.0", diff --git a/javascript/node/selenium-webdriver/BUILD.bazel b/javascript/node/selenium-webdriver/BUILD.bazel index bc6e68042597d..75c855c641ec8 100644 --- a/javascript/node/selenium-webdriver/BUILD.bazel +++ b/javascript/node/selenium-webdriver/BUILD.bazel @@ -33,6 +33,7 @@ js_library( "io/*.js", "lib/*.js", "lib/atoms/bidi-mutation-listener.js", + "lib/fedcm/*.js", "net/*.js", "remote/*.js", "testing/*.js", diff --git a/javascript/node/selenium-webdriver/lib/command.js b/javascript/node/selenium-webdriver/lib/command.js index 5f7f481f77bf6..5d74b955bd4e6 100644 --- a/javascript/node/selenium-webdriver/lib/command.js +++ b/javascript/node/selenium-webdriver/lib/command.js @@ -185,6 +185,17 @@ const Name = { GET_DOWNLOADABLE_FILES: 'getDownloadableFiles', DOWNLOAD_FILE: 'downloadFile', DELETE_DOWNLOADABLE_FILES: 'deleteDownloadableFiles', + + // Federated Credential Management API + // https://www.w3.org/TR/fedcm/#automation + CANCEL_DIALOG: 'cancelDialog', + SELECT_ACCOUNT: 'selectAccount', + GET_ACCOUNTS: 'getAccounts', + GET_FEDCM_TITLE: 'getFedCmTitle', + GET_FEDCM_DIALOG_TYPE: 'getFedCmDialogType', + SET_DELAY_ENABLED: 'setDelayEnabled', + RESET_COOLDOWN: 'resetCooldown', + CLICK_DIALOG_BUTTON: 'clickdialogbutton', } /** diff --git a/javascript/node/selenium-webdriver/lib/fedcm/account.js b/javascript/node/selenium-webdriver/lib/fedcm/account.js new file mode 100644 index 0000000000000..451f192a69f54 --- /dev/null +++ b/javascript/node/selenium-webdriver/lib/fedcm/account.js @@ -0,0 +1,78 @@ +// 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. + +class Account { + constructor( + accountId, + email, + name, + givenName, + pictureUrl, + idpConfigUrl, + loginState, + termsOfServiceUrl, + privacyPolicyUrl, + ) { + this._accountId = accountId + this._email = email + this._name = name + this._givenName = givenName + this._pictureUrl = pictureUrl + this._idpConfigUrl = idpConfigUrl + this._loginState = loginState + this._termsOfServiceUrl = termsOfServiceUrl + this._privacyPolicyUrl = privacyPolicyUrl + } + + get accountId() { + return this._accountId + } + + get email() { + return this._email + } + + get name() { + return this._name + } + + get givenName() { + return this._givenName + } + + get pictureUrl() { + return this._pictureUrl + } + + get idpConfigUrl() { + return this._idpConfigUrl + } + + get loginState() { + return this._loginState + } + + get termsOfServiceUrl() { + return this._termsOfServiceUrl + } + + get privacyPolicyUrl() { + return this._privacyPolicyUrl + } +} + +module.exports = Account diff --git a/javascript/node/selenium-webdriver/lib/fedcm/dialog.js b/javascript/node/selenium-webdriver/lib/fedcm/dialog.js new file mode 100644 index 0000000000000..cec84a78e5d6d --- /dev/null +++ b/javascript/node/selenium-webdriver/lib/fedcm/dialog.js @@ -0,0 +1,76 @@ +// 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. + +const command = require('../command') +const Account = require('./account') + +class Dialog { + constructor(driver) { + this._driver = driver + } + + async title() { + const result = await this._driver.execute(new command.Command(command.Name.GET_FEDCM_TITLE)) + + return result.title + } + + subtitle() { + return this._driver.execute(new command.Command(command.Name.GET_FEDCM_TITLE)) + } + + type() { + return this._driver.execute(new command.Command(command.Name.GET_FEDCM_DIALOG_TYPE)) + } + + async accounts() { + const result = await this._driver.execute(new command.Command(command.Name.GET_ACCOUNTS)) + + const accountArray = [] + + result.forEach((account) => { + const acc = new Account( + account.accountId, + account.email, + account.name, + account.givenName, + account.pictureUrl, + account.idpConfigUrl, + account.loginState, + account.termsOfServiceUrl, + account.privacyPolicyUrl, + ) + accountArray.push(acc) + }) + + return accountArray + } + + selectAccount(index) { + return this._driver.execute(new command.Command(command.Name.SELECT_ACCOUNT).setParameter('accountIndex', index)) + } + + accept() { + return this._driver.execute(new command.Command(command.Name.CLICK_DIALOG_BUTTON)) + } + + dismiss() { + return this._driver.execute(new command.Command(command.Name.CANCEL_DIALOG)) + } +} + +module.exports = Dialog diff --git a/javascript/node/selenium-webdriver/lib/http.js b/javascript/node/selenium-webdriver/lib/http.js index eea7a4fe58d9f..2dd38c43b7169 100644 --- a/javascript/node/selenium-webdriver/lib/http.js +++ b/javascript/node/selenium-webdriver/lib/http.js @@ -320,6 +320,16 @@ const W3C_COMMAND_MAP = new Map([ [cmd.Name.GET_DOWNLOADABLE_FILES, get('/session/:sessionId/se/files')], [cmd.Name.DOWNLOAD_FILE, post(`/session/:sessionId/se/files`)], [cmd.Name.DELETE_DOWNLOADABLE_FILES, del(`/session/:sessionId/se/files`)], + + // Federated Credential Management Command + [cmd.Name.CANCEL_DIALOG, post(`/session/:sessionId/fedcm/canceldialog`)], + [cmd.Name.SELECT_ACCOUNT, post(`/session/:sessionId/fedcm/selectaccount`)], + [cmd.Name.GET_FEDCM_TITLE, get(`/session/:sessionId/fedcm/gettitle`)], + [cmd.Name.GET_FEDCM_DIALOG_TYPE, get('/session/:sessionId/fedcm/getdialogtype')], + [cmd.Name.SET_DELAY_ENABLED, post(`/session/:sessionId/fedcm/setdelayenabled`)], + [cmd.Name.RESET_COOLDOWN, post(`/session/:sessionId/fedcm/resetcooldown`)], + [cmd.Name.CLICK_DIALOG_BUTTON, post(`/session/:sessionId/fedcm/clickdialogbutton`)], + [cmd.Name.GET_ACCOUNTS, get(`/session/:sessionId/fedcm/accountlist`)], ]) /** diff --git a/javascript/node/selenium-webdriver/lib/test/fileserver.js b/javascript/node/selenium-webdriver/lib/test/fileserver.js index 337c1b9205137..d215971f754a2 100644 --- a/javascript/node/selenium-webdriver/lib/test/fileserver.js +++ b/javascript/node/selenium-webdriver/lib/test/fileserver.js @@ -118,7 +118,7 @@ const Pages = (function () { addPage('emptyText', 'bidi/emptyText.txt') addPage('redirectedHttpEquiv', 'bidi/redirected_http_equiv.html') addPage('releaseAction', 'bidi/release_action.html') - + addPage('fedcm', 'fedcm/fedcm_async_js.html') return pages })() diff --git a/javascript/node/selenium-webdriver/lib/webdriver.js b/javascript/node/selenium-webdriver/lib/webdriver.js index 2c6a9aa48e259..d910f54d09bf5 100644 --- a/javascript/node/selenium-webdriver/lib/webdriver.js +++ b/javascript/node/selenium-webdriver/lib/webdriver.js @@ -45,6 +45,7 @@ const { PinnedScript } = require('./pinnedScript') const JSZip = require('jszip') const Script = require('./script') const Network = require('./network') +const Dialog = require('./fedcm/dialog') // Capability names that are defined in the W3C spec. const W3C_CAPABILITY_NAMES = new Set([ @@ -1106,6 +1107,18 @@ class WebDriver { return this.execute(new command.Command(command.Name.SCREENSHOT)) } + setDelayEnabled(enabled) { + return this.execute(new command.Command(command.Name.SET_DELAY_ENABLED).setParameter('enabled', enabled)) + } + + resetCooldown() { + return this.execute(new command.Command(command.Name.RESET_COOLDOWN)) + } + + getFederalCredentialManagementDialog() { + return new Dialog(this) + } + /** @override */ manage() { return new Options(this) diff --git a/javascript/node/selenium-webdriver/test/fedcm/fedcm_test.js b/javascript/node/selenium-webdriver/test/fedcm/fedcm_test.js new file mode 100644 index 0000000000000..4ae3ac70b5706 --- /dev/null +++ b/javascript/node/selenium-webdriver/test/fedcm/fedcm_test.js @@ -0,0 +1,183 @@ +// 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 { Browser } = require('selenium-webdriver') +const { Pages, suite } = require('../../lib/test') +const { By } = require('selenium-webdriver/index') + +suite( + function (env) { + let driver + + beforeEach(async function () { + driver = await env.builder().build() + }) + + afterEach(async function () { + await driver.quit() + }) + + describe('Federated Credential Management Test', function () { + it('credential mangement dialog should appear', async function () { + await driver.get(Pages.fedcm) + + let triggerButton = await driver.findElement(By.id('triggerButton')) + await triggerButton.click() + + let dialog + + await driver.wait( + async () => { + try { + dialog = await driver.getFederalCredentialManagementDialog() + return (await dialog.type()) === 'AccountChooser' + } catch (error) { + return false + } + }, + 10000, + 'Expected dialog type to be "AccountChooser"', + 2000, + ) + + assert.equal(await dialog.type(), 'AccountChooser') + let title = await dialog.title() + assert.equal(title.includes('Sign in to'), true) + }) + + it('can dismiss dialog', async function () { + await driver.get(Pages.fedcm) + + let triggerButton = await driver.findElement(By.id('triggerButton')) + await triggerButton.click() + + let dialog = await driver.getFederalCredentialManagementDialog() + + await driver.wait( + async () => { + try { + return (await dialog.type()) === 'AccountChooser' + } catch (error) { + return false + } + }, + 10000, + 'Expected dialog type to be "AccountChooser"', + 2000, + ) + + assert.equal(await dialog.type(), 'AccountChooser') + let title = await dialog.title() + assert.equal(title.includes('Sign in to'), true) + + await dialog.dismiss() + + try { + await dialog.type() + assert.fail('Above command should throw error') + } catch (error) { + assert.equal(error.message.includes('no such alert'), true) + } + }) + + it('can select account', async function () { + await driver.get(Pages.fedcm) + + let triggerButton = await driver.findElement(By.id('triggerButton')) + await triggerButton.click() + + let dialog = await driver.getFederalCredentialManagementDialog() + + await driver.wait( + async () => { + try { + return (await dialog.type()) === 'AccountChooser' + } catch (error) { + return false + } + }, + 10000, + 'Expected dialog type to be "AccountChooser"', + 2000, + ) + + assert.equal(await dialog.type(), 'AccountChooser') + let title = await dialog.title() + assert.equal(title.includes('Sign in to'), true) + + await dialog.selectAccount(1) + }) + + it('can get account list', async function () { + await driver.get(Pages.fedcm) + + let triggerButton = await driver.findElement(By.id('triggerButton')) + await triggerButton.click() + + let dialog = await driver.getFederalCredentialManagementDialog() + + await driver.wait( + async () => { + try { + return (await dialog.type()) === 'AccountChooser' + } catch (error) { + return false + } + }, + 10000, + 'Expected dialog type to be "AccountChooser"', + 2000, + ) + + assert.equal(await dialog.type(), 'AccountChooser') + let title = await dialog.title() + assert.equal(title.includes('Sign in to'), true) + + const accounts = await dialog.accounts() + + assert.equal(accounts.length, 2) + + const account1 = accounts[0] + const account2 = accounts[1] + + assert.strictEqual(account1.name, 'John Doe') + assert.strictEqual(account1.email, 'john_doe@idp.example') + assert.strictEqual(account1.accountId, '1234') + assert.strictEqual(account1.givenName, 'John') + assert(account1.idpConfigUrl.includes('/fedcm/config.json'), true) + assert.strictEqual(account1.pictureUrl, 'https://idp.example/profile/123') + assert.strictEqual(account1.loginState, 'SignUp') + assert.strictEqual(account1.termsOfServiceUrl, 'https://rp.example/terms_of_service.html') + assert.strictEqual(account1.privacyPolicyUrl, 'https://rp.example/privacy_policy.html') + + assert.strictEqual(account2.name, 'Aisha Ahmad') + assert.strictEqual(account2.email, 'aisha@idp.example') + assert.strictEqual(account2.accountId, '5678') + assert.strictEqual(account2.givenName, 'Aisha') + assert(account2.idpConfigUrl.includes('/fedcm/config.json'), true) + assert.strictEqual(account2.pictureUrl, 'https://idp.example/profile/567') + assert.strictEqual(account2.loginState, 'SignUp') + assert.strictEqual(account2.termsOfServiceUrl, 'https://rp.example/terms_of_service.html') + assert.strictEqual(account2.privacyPolicyUrl, 'https://rp.example/privacy_policy.html') + }) + }) + }, + { browsers: [Browser.CHROME, Browser.EDGE] }, +) diff --git a/package.json b/package.json index 57278a663f412..dc0b5f15736a9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "selenium", - "packageManager": "pnpm@9.6.0", + "packageManager": "pnpm@9.15.2", "workspaces": [ "javascript/grid-ui", "javascript/node/selenium-webdriver" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index bc3d00e8d2a1e..724898d079723 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -12,19 +12,19 @@ importers: dependencies: '@apollo/client': specifier: 3.12.4 - version: 3.12.4(@types/react@18.2.72)(graphql@16.10.0)(react-dom@18.3.1)(react@18.3.1) + version: 3.12.4(@types/react@18.3.18)(graphql@16.10.0)(react-dom@18.3.1)(react@18.3.1) '@emotion/react': specifier: 11.14.0 - version: 11.14.0(@types/react@18.2.72)(react@18.3.1) + version: 11.14.0(@types/react@18.3.18)(react@18.3.1) '@emotion/styled': specifier: 11.14.0 - version: 11.14.0(@emotion/react@11.14.0)(@types/react@18.2.72)(react@18.3.1) + version: 11.14.0(@emotion/react@11.14.0)(@types/react@18.3.18)(react@18.3.1) '@mui/icons-material': specifier: 5.15.18 - version: 5.15.18(@mui/material@5.15.18)(@types/react@18.2.72)(react@18.3.1) + version: 5.15.18(@mui/material@5.15.18)(@types/react@18.3.18)(react@18.3.1) '@mui/material': specifier: 5.15.18 - version: 5.15.18(@emotion/react@11.14.0)(@emotion/styled@11.14.0)(@types/react@18.2.72)(react-dom@18.3.1)(react@18.3.1) + version: 5.15.18(@emotion/react@11.14.0)(@emotion/styled@11.14.0)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) '@novnc/novnc': specifier: 1.5.0 version: 1.5.0 @@ -35,11 +35,11 @@ importers: specifier: 20.12.12 version: 20.12.12 '@types/react': - specifier: 18.2.72 - version: 18.2.72 + specifier: 18.3.18 + version: 18.3.18 '@types/react-dom': - specifier: 18.2.22 - version: 18.2.22 + specifier: 18.3.5 + version: 18.3.5(@types/react@18.3.18) '@types/react-modal': specifier: 3.16.3 version: 3.16.3 @@ -82,7 +82,7 @@ importers: version: 6.6.3 '@testing-library/react': specifier: 14.3.1 - version: 14.3.1(react-dom@18.3.1)(react@18.3.1) + version: 14.3.1(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) '@testing-library/user-event': specifier: 14.5.2 version: 14.5.2(@testing-library/dom@10.4.0) @@ -182,7 +182,7 @@ packages: '@jridgewell/gen-mapping': 0.3.8 '@jridgewell/trace-mapping': 0.3.25 - /@apollo/client@3.12.4(@types/react@18.2.72)(graphql@16.10.0)(react-dom@18.3.1)(react@18.3.1): + /@apollo/client@3.12.4(@types/react@18.3.18)(graphql@16.10.0)(react-dom@18.3.1)(react@18.3.1): resolution: {integrity: sha512-S/eC9jxEW9Jg1BjD6AZonE1fHxYuvC3gFHop8FRQkUdeK63MmBD5r0DOrN2WlJbwha1MSD6A97OwXwjaujEQpA==} peerDependencies: graphql: ^15.0.0 || ^16.0.0 @@ -211,7 +211,7 @@ packages: prop-types: 15.8.1 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - rehackt: 0.1.0(@types/react@18.2.72)(react@18.3.1) + rehackt: 0.1.0(@types/react@18.3.18)(react@18.3.1) response-iterator: 0.2.6 symbol-observable: 4.0.0 ts-invariant: 0.10.3 @@ -492,7 +492,7 @@ packages: resolution: {integrity: sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==} dev: false - /@emotion/react@11.14.0(@types/react@18.2.72)(react@18.3.1): + /@emotion/react@11.14.0(@types/react@18.3.18)(react@18.3.1): resolution: {integrity: sha512-O000MLDBDdk/EohJPFUqvnp4qnHeYkVP5B0xEG0D/L7cOKP9kefu2DXn8dj74cQfsEzUqh+sr1RzFqiL1o+PpA==} peerDependencies: '@types/react': '*' @@ -508,7 +508,7 @@ packages: '@emotion/use-insertion-effect-with-fallbacks': 1.2.0(react@18.3.1) '@emotion/utils': 1.4.2 '@emotion/weak-memoize': 0.4.0 - '@types/react': 18.2.72 + '@types/react': 18.3.18 hoist-non-react-statics: 3.3.2 react: 18.3.1 transitivePeerDependencies: @@ -529,7 +529,7 @@ packages: resolution: {integrity: sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg==} dev: false - /@emotion/styled@11.14.0(@emotion/react@11.14.0)(@types/react@18.2.72)(react@18.3.1): + /@emotion/styled@11.14.0(@emotion/react@11.14.0)(@types/react@18.3.18)(react@18.3.1): resolution: {integrity: sha512-XxfOnXFffatap2IyCeJyNov3kiDQWoR08gPUQxvbL7fxKryGBKUZUkG6Hz48DZwVrJSVh9sJboyV1Ds4OW6SgA==} peerDependencies: '@emotion/react': ^11.0.0-rc.0 @@ -542,11 +542,11 @@ packages: '@babel/runtime': 7.26.0 '@emotion/babel-plugin': 11.13.5 '@emotion/is-prop-valid': 1.3.1 - '@emotion/react': 11.14.0(@types/react@18.2.72)(react@18.3.1) + '@emotion/react': 11.14.0(@types/react@18.3.18)(react@18.3.1) '@emotion/serialize': 1.3.3 '@emotion/use-insertion-effect-with-fallbacks': 1.2.0(react@18.3.1) '@emotion/utils': 1.4.2 - '@types/react': 18.2.72 + '@types/react': 18.3.18 react: 18.3.1 transitivePeerDependencies: - supports-color @@ -1054,7 +1054,7 @@ packages: lodash: 4.17.21 dev: true - /@mui/base@5.0.0-beta.40(@types/react@18.2.72)(react-dom@18.3.1)(react@18.3.1): + /@mui/base@5.0.0-beta.40(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1): resolution: {integrity: sha512-I/lGHztkCzvwlXpjD2+SNmvNQvB4227xBXhISPjEaJUXGImOQ9f3D2Yj/T3KasSI/h0MLWy74X0J6clhPmsRbQ==} engines: {node: '>=12.0.0'} peerDependencies: @@ -1067,10 +1067,10 @@ packages: dependencies: '@babel/runtime': 7.26.0 '@floating-ui/react-dom': 2.1.2(react-dom@18.3.1)(react@18.3.1) - '@mui/types': 7.2.20(@types/react@18.2.72) - '@mui/utils': 5.16.13(@types/react@18.2.72)(react@18.3.1) + '@mui/types': 7.2.21(@types/react@18.3.18) + '@mui/utils': 5.16.13(@types/react@18.3.18)(react@18.3.1) '@popperjs/core': 2.11.8 - '@types/react': 18.2.72 + '@types/react': 18.3.18 clsx: 2.1.1 prop-types: 15.8.1 react: 18.3.1 @@ -1081,7 +1081,7 @@ packages: resolution: {integrity: sha512-xe5RwI0Q2O709Bd2Y7l1W1NIwNmln0y+xaGk5VgX3vDJbkQEqzdfTFZ73e0CkEZgJwyiWgk5HY0l8R4nysOxjw==} dev: false - /@mui/icons-material@5.15.18(@mui/material@5.15.18)(@types/react@18.2.72)(react@18.3.1): + /@mui/icons-material@5.15.18(@mui/material@5.15.18)(@types/react@18.3.18)(react@18.3.1): resolution: {integrity: sha512-jGhyw02TSLM0NgW+MDQRLLRUD/K4eN9rlK2pTBTL1OtzyZmQ8nB060zK1wA0b7cVrIiG+zyrRmNAvGWXwm2N9Q==} engines: {node: '>=12.0.0'} peerDependencies: @@ -1093,12 +1093,12 @@ packages: optional: true dependencies: '@babel/runtime': 7.26.0 - '@mui/material': 5.15.18(@emotion/react@11.14.0)(@emotion/styled@11.14.0)(@types/react@18.2.72)(react-dom@18.3.1)(react@18.3.1) - '@types/react': 18.2.72 + '@mui/material': 5.15.18(@emotion/react@11.14.0)(@emotion/styled@11.14.0)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) + '@types/react': 18.3.18 react: 18.3.1 dev: false - /@mui/material@5.15.18(@emotion/react@11.14.0)(@emotion/styled@11.14.0)(@types/react@18.2.72)(react-dom@18.3.1)(react@18.3.1): + /@mui/material@5.15.18(@emotion/react@11.14.0)(@emotion/styled@11.14.0)(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1): resolution: {integrity: sha512-n+/dsiqux74fFfcRUJjok+ieNQ7+BEk6/OwX9cLcLvriZrZb+/7Y8+Fd2HlUUbn5N0CDurgAHm0VH1DqyJ9HAw==} engines: {node: '>=12.0.0'} peerDependencies: @@ -1116,15 +1116,15 @@ packages: optional: true dependencies: '@babel/runtime': 7.26.0 - '@emotion/react': 11.14.0(@types/react@18.2.72)(react@18.3.1) - '@emotion/styled': 11.14.0(@emotion/react@11.14.0)(@types/react@18.2.72)(react@18.3.1) - '@mui/base': 5.0.0-beta.40(@types/react@18.2.72)(react-dom@18.3.1)(react@18.3.1) + '@emotion/react': 11.14.0(@types/react@18.3.18)(react@18.3.1) + '@emotion/styled': 11.14.0(@emotion/react@11.14.0)(@types/react@18.3.18)(react@18.3.1) + '@mui/base': 5.0.0-beta.40(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1) '@mui/core-downloads-tracker': 5.16.13 - '@mui/system': 5.16.13(@emotion/react@11.14.0)(@emotion/styled@11.14.0)(@types/react@18.2.72)(react@18.3.1) - '@mui/types': 7.2.20(@types/react@18.2.72) - '@mui/utils': 5.16.13(@types/react@18.2.72)(react@18.3.1) - '@types/react': 18.2.72 - '@types/react-transition-group': 4.4.12(@types/react@18.2.72) + '@mui/system': 5.16.13(@emotion/react@11.14.0)(@emotion/styled@11.14.0)(@types/react@18.3.18)(react@18.3.1) + '@mui/types': 7.2.21(@types/react@18.3.18) + '@mui/utils': 5.16.13(@types/react@18.3.18)(react@18.3.1) + '@types/react': 18.3.18 + '@types/react-transition-group': 4.4.12(@types/react@18.3.18) clsx: 2.1.1 csstype: 3.1.3 prop-types: 15.8.1 @@ -1134,7 +1134,7 @@ packages: react-transition-group: 4.4.5(react-dom@18.3.1)(react@18.3.1) dev: false - /@mui/private-theming@5.16.13(@types/react@18.2.72)(react@18.3.1): + /@mui/private-theming@5.16.13(@types/react@18.3.18)(react@18.3.1): resolution: {integrity: sha512-+s0FklvDvO7j0yBZn19DIIT3rLfub2fWvXGtMX49rG/xHfDFcP7fbWbZKHZMMP/2/IoTRDrZCbY1iP0xZlmuJA==} engines: {node: '>=12.0.0'} peerDependencies: @@ -1145,8 +1145,8 @@ packages: optional: true dependencies: '@babel/runtime': 7.26.0 - '@mui/utils': 5.16.13(@types/react@18.2.72)(react@18.3.1) - '@types/react': 18.2.72 + '@mui/utils': 5.16.13(@types/react@18.3.18)(react@18.3.1) + '@types/react': 18.3.18 prop-types: 15.8.1 react: 18.3.1 dev: false @@ -1166,14 +1166,14 @@ packages: dependencies: '@babel/runtime': 7.26.0 '@emotion/cache': 11.14.0 - '@emotion/react': 11.14.0(@types/react@18.2.72)(react@18.3.1) - '@emotion/styled': 11.14.0(@emotion/react@11.14.0)(@types/react@18.2.72)(react@18.3.1) + '@emotion/react': 11.14.0(@types/react@18.3.18)(react@18.3.1) + '@emotion/styled': 11.14.0(@emotion/react@11.14.0)(@types/react@18.3.18)(react@18.3.1) csstype: 3.1.3 prop-types: 15.8.1 react: 18.3.1 dev: false - /@mui/system@5.16.13(@emotion/react@11.14.0)(@emotion/styled@11.14.0)(@types/react@18.2.72)(react@18.3.1): + /@mui/system@5.16.13(@emotion/react@11.14.0)(@emotion/styled@11.14.0)(@types/react@18.3.18)(react@18.3.1): resolution: {integrity: sha512-JnO3VH3yNoAmgyr44/2jiS1tcNwshwAqAaG5fTEEjHQbkuZT/mvPYj2GC1cON0zEQ5V03xrCNl/D+gU9AXibpw==} engines: {node: '>=12.0.0'} peerDependencies: @@ -1190,31 +1190,31 @@ packages: optional: true dependencies: '@babel/runtime': 7.26.0 - '@emotion/react': 11.14.0(@types/react@18.2.72)(react@18.3.1) - '@emotion/styled': 11.14.0(@emotion/react@11.14.0)(@types/react@18.2.72)(react@18.3.1) - '@mui/private-theming': 5.16.13(@types/react@18.2.72)(react@18.3.1) + '@emotion/react': 11.14.0(@types/react@18.3.18)(react@18.3.1) + '@emotion/styled': 11.14.0(@emotion/react@11.14.0)(@types/react@18.3.18)(react@18.3.1) + '@mui/private-theming': 5.16.13(@types/react@18.3.18)(react@18.3.1) '@mui/styled-engine': 5.16.13(@emotion/react@11.14.0)(@emotion/styled@11.14.0)(react@18.3.1) - '@mui/types': 7.2.20(@types/react@18.2.72) - '@mui/utils': 5.16.13(@types/react@18.2.72)(react@18.3.1) - '@types/react': 18.2.72 + '@mui/types': 7.2.21(@types/react@18.3.18) + '@mui/utils': 5.16.13(@types/react@18.3.18)(react@18.3.1) + '@types/react': 18.3.18 clsx: 2.1.1 csstype: 3.1.3 prop-types: 15.8.1 react: 18.3.1 dev: false - /@mui/types@7.2.20(@types/react@18.2.72): - resolution: {integrity: sha512-straFHD7L8v05l/N5vcWk+y7eL9JF0C2mtph/y4BPm3gn2Eh61dDwDB65pa8DLss3WJfDXYC7Kx5yjP0EmXpgw==} + /@mui/types@7.2.21(@types/react@18.3.18): + resolution: {integrity: sha512-6HstngiUxNqLU+/DPqlUJDIPbzUBxIVHb1MmXP0eTWDIROiCR2viugXpEif0PPe2mLqqakPzzRClWAnK+8UJww==} peerDependencies: '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0 peerDependenciesMeta: '@types/react': optional: true dependencies: - '@types/react': 18.2.72 + '@types/react': 18.3.18 dev: false - /@mui/utils@5.16.13(@types/react@18.2.72)(react@18.3.1): + /@mui/utils@5.16.13(@types/react@18.3.18)(react@18.3.1): resolution: {integrity: sha512-35kLiShnDPByk57Mz4PP66fQUodCFiOD92HfpW6dK9lc7kjhZsKHRKeYPgWuwEHeXwYsCSFtBCW4RZh/8WT+TQ==} engines: {node: '>=12.0.0'} peerDependencies: @@ -1225,9 +1225,9 @@ packages: optional: true dependencies: '@babel/runtime': 7.26.0 - '@mui/types': 7.2.20(@types/react@18.2.72) + '@mui/types': 7.2.21(@types/react@18.3.18) '@types/prop-types': 15.7.14 - '@types/react': 18.2.72 + '@types/react': 18.3.18 clsx: 2.1.1 prop-types: 15.8.1 react: 18.3.1 @@ -1353,7 +1353,7 @@ packages: redent: 3.0.0 dev: true - /@testing-library/react@14.3.1(react-dom@18.3.1)(react@18.3.1): + /@testing-library/react@14.3.1(@types/react@18.3.18)(react-dom@18.3.1)(react@18.3.1): resolution: {integrity: sha512-H99XjUhWQw0lTgyMN05W3xQG1Nh4lq574D8keFf1dDoNTJgp66VbJozRaczoF+wsiaPJNt/TcnfpLGufGxSrZQ==} engines: {node: '>=14'} peerDependencies: @@ -1362,9 +1362,11 @@ packages: dependencies: '@babel/runtime': 7.26.0 '@testing-library/dom': 9.3.4 - '@types/react-dom': 18.2.22 + '@types/react-dom': 18.3.5(@types/react@18.3.18) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) + transitivePeerDependencies: + - '@types/react' dev: true /@testing-library/user-event@14.5.2(@testing-library/dom@10.4.0): @@ -1447,22 +1449,24 @@ packages: /@types/prop-types@15.7.14: resolution: {integrity: sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ==} - /@types/react-dom@18.2.22: - resolution: {integrity: sha512-fHkBXPeNtfvri6gdsMYyW+dW7RXFo6Ad09nLFK0VQWR7yGLai/Cyvyj696gbwYvBnhGtevUG9cET0pmUbMtoPQ==} + /@types/react-dom@18.3.5(@types/react@18.3.18): + resolution: {integrity: sha512-P4t6saawp+b/dFrUr2cvkVsfvPguwsxtH6dNIYRllMsefqFzkZk5UIjzyDOv5g1dXIPdG4Sp1yCR4Z6RCUsG/Q==} + peerDependencies: + '@types/react': ^18.0.0 dependencies: - '@types/react': 18.2.72 + '@types/react': 18.3.18 /@types/react-modal@3.16.3: resolution: {integrity: sha512-xXuGavyEGaFQDgBv4UVm8/ZsG+qxeQ7f77yNrW3n+1J6XAstUy5rYHeIHPh1KzsGc6IkCIdu6lQ2xWzu1jBTLg==} dependencies: - '@types/react': 18.2.72 + '@types/react': 18.3.18 dev: false /@types/react-router-dom@5.3.3: resolution: {integrity: sha512-kpqnYK4wcdm5UaWI3fLcELopqLrHgLqNsdpHauzlQktfkHL3npOSwtj1Uz9oKBAzs7lFtVkV8j83voAz2D8fhw==} dependencies: '@types/history': 4.7.11 - '@types/react': 18.2.72 + '@types/react': 18.3.18 '@types/react-router': 5.1.20 dev: false @@ -1470,19 +1474,19 @@ packages: resolution: {integrity: sha512-jGjmu/ZqS7FjSH6owMcD5qpq19+1RS9DeVRqfl1FeBMxTDQAGwlMWOcs52NDoXaNKyG3d1cYQFMs9rCrb88o9Q==} dependencies: '@types/history': 4.7.11 - '@types/react': 18.2.72 + '@types/react': 18.3.18 dev: false - /@types/react-transition-group@4.4.12(@types/react@18.2.72): + /@types/react-transition-group@4.4.12(@types/react@18.3.18): resolution: {integrity: sha512-8TV6R3h2j7a91c+1DXdJi3Syo69zzIZbz7Lg5tORM5LEJG7X/E6a1V3drRyBRZq7/utz7A+c4OgYLiLcYGHG6w==} peerDependencies: '@types/react': '*' dependencies: - '@types/react': 18.2.72 + '@types/react': 18.3.18 dev: false - /@types/react@18.2.72: - resolution: {integrity: sha512-/e7GWxGzXQF7OJAua7UAYqYi/4VpXEfbGtmYQcAQwP3SjjjAXfybTf/JK5S+SaetB/ChXl8Y2g1hCsj7jDXxcg==} + /@types/react@18.3.18: + resolution: {integrity: sha512-t4yC+vtgnkYjNSKlFx1jkAhH8LgTo2N/7Qvi83kdEaUtMDiwpbLAktKDaAMlRcJ5eSxZkH74eEGt1ky31d7kfQ==} dependencies: '@types/prop-types': 15.7.14 csstype: 3.1.3 @@ -5110,7 +5114,7 @@ packages: engines: {node: '>=8'} dev: true - /rehackt@0.1.0(@types/react@18.2.72)(react@18.3.1): + /rehackt@0.1.0(@types/react@18.3.18)(react@18.3.1): resolution: {integrity: sha512-7kRDOuLHB87D/JESKxQoRwv4DzbIdwkAGQ7p6QKGdVlY1IZheUnVhlk/4UZlNUVxdAXpyxikE3URsG067ybVzw==} peerDependencies: '@types/react': '*' @@ -5121,7 +5125,7 @@ packages: react: optional: true dependencies: - '@types/react': 18.2.72 + '@types/react': 18.3.18 react: 18.3.1 dev: false diff --git a/py/requirements.txt b/py/requirements.txt index 3dfbe58c683ab..aef1b0f79400f 100644 --- a/py/requirements.txt +++ b/py/requirements.txt @@ -7,7 +7,7 @@ secretstorage==3.3.3 debugpy==1.8.11 filetype==1.2.0 h11==0.14.0 -idna==3.7 +idna==3.10 importlib-metadata==6.8.0 inflection==0.5.1 iniconfig==2.0.0 diff --git a/py/requirements_lock.txt b/py/requirements_lock.txt index a081808cccea8..6831a495cc0f3 100644 --- a/py/requirements_lock.txt +++ b/py/requirements_lock.txt @@ -257,9 +257,9 @@ h11==0.14.0 \ # via # -r py/requirements.txt # wsproto -idna==3.7 \ - --hash=sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc \ - --hash=sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0 +idna==3.10 \ + --hash=sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9 \ + --hash=sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3 # via # -r py/requirements.txt # requests diff --git a/renovate.json b/renovate.json index f5aba04d1c54e..e03df565fa82a 100644 --- a/renovate.json +++ b/renovate.json @@ -39,6 +39,7 @@ }, { "matchManagers": [ "npm" ], + "rangeStrategy": "bump", "commitMessagePrefix": "[js]", "labels": [ "dependencies", "c-nodejs" ] }, @@ -69,6 +70,7 @@ }, { "matchManagers": [ "cargo" ], + "rangeStrategy": "bump", "commitMessagePrefix": "[rust]", "labels": [ "dependencies", "c-rust" ] },