From 767c7c0cf1c01857a0d9814675e98f97bcc1171c Mon Sep 17 00:00:00 2001 From: Nikolay Borisenko <22616990+nvborisenko@users.noreply.github.com> Date: Mon, 9 Dec 2024 21:17:58 +0300 Subject: [PATCH 1/7] Simplify --- dotnet/src/webdriver/CookieJar.cs | 76 ++++++++----------------------- 1 file changed, 20 insertions(+), 56 deletions(-) diff --git a/dotnet/src/webdriver/CookieJar.cs b/dotnet/src/webdriver/CookieJar.cs index e4f681e11908a..3ac4ddb10102a 100644 --- a/dotnet/src/webdriver/CookieJar.cs +++ b/dotnet/src/webdriver/CookieJar.cs @@ -23,77 +23,45 @@ namespace OpenQA.Selenium { - /// - /// Defines an interface allowing the user to manipulate cookies on the current page. - /// - internal class CookieJar : ICookieJar + internal class CookieJar(WebDriver driver) : ICookieJar { - private WebDriver driver; + public ReadOnlyCollection AllCookies => GetAllCookies(); - /// - /// Initializes a new instance of the class. - /// - /// The driver that is currently in use - public CookieJar(WebDriver driver) - { - this.driver = driver; - } - - /// - /// Gets all cookies defined for the current page. - /// - public ReadOnlyCollection AllCookies - { - get { return this.GetAllCookies(); } - } - - /// - /// Method for creating a cookie in the browser - /// - /// that represents a cookie in the browser public void AddCookie(Cookie cookie) { - Dictionary parameters = new Dictionary(); - parameters.Add("cookie", cookie); - this.driver.InternalExecute(DriverCommand.AddCookie, parameters); + if (cookie is null) + { + throw new ArgumentNullException(nameof(cookie)); + } + + driver.InternalExecute(DriverCommand.AddCookie, new() { { "cookie", cookie } }); } - /// - /// Delete the cookie by passing in the name of the cookie - /// - /// The name of the cookie that is in the browser public void DeleteCookieNamed(string name) { - Dictionary parameters = new Dictionary(); - parameters.Add("name", name); - this.driver.InternalExecute(DriverCommand.DeleteCookie, parameters); + if (name is null) + { + throw new ArgumentNullException(nameof(name)); + } + + driver.InternalExecute(DriverCommand.DeleteCookie, new() { { "name", name } }); } - /// - /// Delete a cookie in the browser by passing in a copy of a cookie - /// - /// An object that represents a copy of the cookie that needs to be deleted public void DeleteCookie(Cookie cookie) { - if (cookie != null) + if (cookie is null) { - this.DeleteCookieNamed(cookie.Name); + throw new ArgumentNullException(nameof(cookie)); } + + DeleteCookieNamed(cookie.Name); } - /// - /// Delete All Cookies that are present in the browser - /// public void DeleteAllCookies() { - this.driver.InternalExecute(DriverCommand.DeleteAllCookies, null); + driver.InternalExecute(DriverCommand.DeleteAllCookies, null); } - /// - /// Method for returning a getting a cookie by name - /// - /// name of the cookie that needs to be returned - /// A Cookie from the name public Cookie GetCookieNamed(string name) { Cookie cookieToReturn = null; @@ -113,14 +81,10 @@ public Cookie GetCookieNamed(string name) return cookieToReturn; } - /// - /// Method for getting a Collection of Cookies that are present in the browser - /// - /// ReadOnlyCollection of Cookies in the browser private ReadOnlyCollection GetAllCookies() { List toReturn = new List(); - object returned = this.driver.InternalExecute(DriverCommand.GetAllCookies, new Dictionary()).Value; + object returned = driver.InternalExecute(DriverCommand.GetAllCookies, new Dictionary()).Value; try { From 3c5ebb79d0093d8bd43b5742844fc5c150266afe Mon Sep 17 00:00:00 2001 From: Nikolay Borisenko <22616990+nvborisenko@users.noreply.github.com> Date: Mon, 9 Dec 2024 21:27:39 +0300 Subject: [PATCH 2/7] Use new remote endpoint --- dotnet/src/webdriver/CookieJar.cs | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/dotnet/src/webdriver/CookieJar.cs b/dotnet/src/webdriver/CookieJar.cs index 3ac4ddb10102a..eac1840f7eb5d 100644 --- a/dotnet/src/webdriver/CookieJar.cs +++ b/dotnet/src/webdriver/CookieJar.cs @@ -64,21 +64,14 @@ public void DeleteAllCookies() public Cookie GetCookieNamed(string name) { - Cookie cookieToReturn = null; - if (name != null) + if (name is null) { - ReadOnlyCollection allCookies = this.AllCookies; - foreach (Cookie currentCookie in allCookies) - { - if (name.Equals(currentCookie.Name)) - { - cookieToReturn = currentCookie; - break; - } - } + throw new ArgumentNullException("{nameof(name)}"); } - return cookieToReturn; + var rawCookie = driver.InternalExecute($"{DriverCommand.GetCookie}/{name}", null).Value; + + return Cookie.FromDictionary(rawCookie as Dictionary); } private ReadOnlyCollection GetAllCookies() From 73cb988a0dab720b9edd5c516d1ac5a9f4234568 Mon Sep 17 00:00:00 2001 From: Nikolay Borisenko <22616990+nvborisenko@users.noreply.github.com> Date: Mon, 9 Dec 2024 21:53:55 +0300 Subject: [PATCH 3/7] Introduce NoSuchCookieException --- dotnet/src/webdriver/CookieJar.cs | 4 +- dotnet/src/webdriver/NoSuchCookieException.cs | 63 +++++++++++++++++++ .../W3CWireProtocolCommandInfoRepository.cs | 2 +- dotnet/src/webdriver/WebDriver.cs | 3 + 4 files changed, 69 insertions(+), 3 deletions(-) create mode 100644 dotnet/src/webdriver/NoSuchCookieException.cs diff --git a/dotnet/src/webdriver/CookieJar.cs b/dotnet/src/webdriver/CookieJar.cs index eac1840f7eb5d..6f3c8b8699687 100644 --- a/dotnet/src/webdriver/CookieJar.cs +++ b/dotnet/src/webdriver/CookieJar.cs @@ -66,10 +66,10 @@ public Cookie GetCookieNamed(string name) { if (name is null) { - throw new ArgumentNullException("{nameof(name)}"); + throw new ArgumentNullException(nameof(name)); } - var rawCookie = driver.InternalExecute($"{DriverCommand.GetCookie}/{name}", null).Value; + var rawCookie = driver.InternalExecute(DriverCommand.GetCookie, new() { { "name", name } }).Value; return Cookie.FromDictionary(rawCookie as Dictionary); } diff --git a/dotnet/src/webdriver/NoSuchCookieException.cs b/dotnet/src/webdriver/NoSuchCookieException.cs new file mode 100644 index 0000000000000..067a89eba6465 --- /dev/null +++ b/dotnet/src/webdriver/NoSuchCookieException.cs @@ -0,0 +1,63 @@ +// +// 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. +// + +using System; + +#nullable enable + +namespace OpenQA.Selenium +{ + /// + /// The exception that is thrown when a cookie is not found. + /// + [Serializable] + public class NoSuchCookieException : NotFoundException + { + /// + /// Initializes a new instance of the class. + /// + public NoSuchCookieException() + : base() + { + } + + /// + /// Initializes a new instance of the class with + /// a specified error message. + /// + /// The message that describes the error. + public NoSuchCookieException(string? message) + : base(message) + { + } + + /// + /// Initializes a new instance of the class with + /// a specified error message and a reference to the inner exception that is the + /// cause of this exception. + /// + /// The error message that explains the reason for the exception. + /// The exception that is the cause of the current exception, + /// or if no inner exception is specified. + public NoSuchCookieException(string? message, Exception? innerException) + : base(message, innerException) + { + } + } +} diff --git a/dotnet/src/webdriver/Remote/W3CWireProtocolCommandInfoRepository.cs b/dotnet/src/webdriver/Remote/W3CWireProtocolCommandInfoRepository.cs index 8c51b36fd6035..352194e7bca41 100644 --- a/dotnet/src/webdriver/Remote/W3CWireProtocolCommandInfoRepository.cs +++ b/dotnet/src/webdriver/Remote/W3CWireProtocolCommandInfoRepository.cs @@ -108,7 +108,7 @@ protected override void InitializeCommandDictionary() this.TryAddCommand(DriverCommand.ExecuteScript, new HttpCommandInfo(HttpCommandInfo.PostCommand, "/session/{sessionId}/execute/sync")); this.TryAddCommand(DriverCommand.ExecuteAsyncScript, new HttpCommandInfo(HttpCommandInfo.PostCommand, "/session/{sessionId}/execute/async")); this.TryAddCommand(DriverCommand.GetAllCookies, new HttpCommandInfo(HttpCommandInfo.GetCommand, "/session/{sessionId}/cookie")); - this.TryAddCommand(DriverCommand.GetCookie, new HttpCommandInfo(HttpCommandInfo.PostCommand, "/session/{sessionId}/cookie/{name}")); + this.TryAddCommand(DriverCommand.GetCookie, new HttpCommandInfo(HttpCommandInfo.GetCommand, "/session/{sessionId}/cookie/{name}")); this.TryAddCommand(DriverCommand.AddCookie, new HttpCommandInfo(HttpCommandInfo.PostCommand, "/session/{sessionId}/cookie")); this.TryAddCommand(DriverCommand.DeleteCookie, new HttpCommandInfo(HttpCommandInfo.DeleteCommand, "/session/{sessionId}/cookie/{name}")); this.TryAddCommand(DriverCommand.DeleteAllCookies, new HttpCommandInfo(HttpCommandInfo.DeleteCommand, "/session/{sessionId}/cookie")); diff --git a/dotnet/src/webdriver/WebDriver.cs b/dotnet/src/webdriver/WebDriver.cs index 9bcca8b28f8b3..f887ce42bd432 100644 --- a/dotnet/src/webdriver/WebDriver.cs +++ b/dotnet/src/webdriver/WebDriver.cs @@ -853,6 +853,9 @@ private static void UnpackAndThrowOnError(Response errorResponse, string command case WebDriverResult.InsecureCertificate: throw new InsecureCertificateException(errorMessage); + case WebDriverResult.NoSuchCookie: + throw new NoSuchCookieException(errorMessage); + default: throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "{0} ({1})", errorMessage, errorResponse.Status)); } From 639e8cae08946469019a3f17bad768dc610d43fc Mon Sep 17 00:00:00 2001 From: Nikolay Borisenko <22616990+nvborisenko@users.noreply.github.com> Date: Mon, 9 Dec 2024 22:02:43 +0300 Subject: [PATCH 4/7] Docs for ArgumentNullException methods --- dotnet/src/webdriver/ICookieJar.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/dotnet/src/webdriver/ICookieJar.cs b/dotnet/src/webdriver/ICookieJar.cs index a27c472a78c41..4df84a182e653 100644 --- a/dotnet/src/webdriver/ICookieJar.cs +++ b/dotnet/src/webdriver/ICookieJar.cs @@ -17,6 +17,7 @@ // under the License. // +using System; using System.Collections.ObjectModel; namespace OpenQA.Selenium @@ -35,6 +36,7 @@ public interface ICookieJar /// Adds a cookie to the current page. /// /// The object to be added. + /// If is . void AddCookie(Cookie cookie); /// @@ -43,18 +45,22 @@ public interface ICookieJar /// The name of the cookie to retrieve. /// The containing the name. Returns /// if no cookie with the specified name is found. + /// If is . + /// If is not found. Cookie GetCookieNamed(string name); /// /// Deletes the specified cookie from the page. /// /// The to be deleted. + /// If is . void DeleteCookie(Cookie cookie); /// /// Deletes the cookie with the specified name from the page. /// /// The name of the cookie to be deleted. + /// If is . void DeleteCookieNamed(string name); /// From 1b5ec71d714e59f672c475dffde75b328103ec7e Mon Sep 17 00:00:00 2001 From: Nikolay Borisenko <22616990+nvborisenko@users.noreply.github.com> Date: Mon, 9 Dec 2024 22:08:24 +0300 Subject: [PATCH 5/7] Fix docs for new behavior --- dotnet/src/webdriver/ICookieJar.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/dotnet/src/webdriver/ICookieJar.cs b/dotnet/src/webdriver/ICookieJar.cs index 4df84a182e653..c0e1eab1d824e 100644 --- a/dotnet/src/webdriver/ICookieJar.cs +++ b/dotnet/src/webdriver/ICookieJar.cs @@ -43,8 +43,7 @@ public interface ICookieJar /// Gets a cookie with the specified name. /// /// The name of the cookie to retrieve. - /// The containing the name. Returns - /// if no cookie with the specified name is found. + /// The containing the name. /// If is . /// If is not found. Cookie GetCookieNamed(string name); From 3f156faa25fa18ddd00d26e9fe4526663f309ae6 Mon Sep 17 00:00:00 2001 From: Nikolay Borisenko <22616990+nvborisenko@users.noreply.github.com> Date: Mon, 9 Dec 2024 22:32:03 +0300 Subject: [PATCH 6/7] Adjust tests --- dotnet/test/common/CookieImplementationTest.cs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/dotnet/test/common/CookieImplementationTest.cs b/dotnet/test/common/CookieImplementationTest.cs index a329895d79b7d..6b60192252ec1 100644 --- a/dotnet/test/common/CookieImplementationTest.cs +++ b/dotnet/test/common/CookieImplementationTest.cs @@ -553,8 +553,7 @@ public void SettingACookieThatExpiredInThePast() IOptions options = driver.Manage(); options.Cookies.AddCookie(cookie); - cookie = options.Cookies.GetCookieNamed("expired"); - Assert.That(cookie, Is.Null, "Cookie expired before it was set, so nothing should be returned: " + cookie); + Assert.That(() => options.Cookies.GetCookieNamed("expired"), Throws.InstanceOf()); } [Test] @@ -579,9 +578,8 @@ public void CanSetCookieWithoutOptionalFieldsSet() public void DeleteNotExistedCookie() { String key = GenerateUniqueKey(); - AssertCookieIsNotPresentWithName(key); - driver.Manage().Cookies.DeleteCookieNamed(key); + Assert.That(() => driver.Manage().Cookies.DeleteCookieNamed(key), Throws.Nothing); } [Test] From e78fbda0d81cf57a8cc9bf49e177a0aa9315370a Mon Sep 17 00:00:00 2001 From: Nikolay Borisenko <22616990+nvborisenko@users.noreply.github.com> Date: Mon, 9 Dec 2024 22:46:26 +0300 Subject: [PATCH 7/7] Explicit cast of raw cookie object --- dotnet/src/webdriver/CookieJar.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dotnet/src/webdriver/CookieJar.cs b/dotnet/src/webdriver/CookieJar.cs index 6f3c8b8699687..934c50892cc3c 100644 --- a/dotnet/src/webdriver/CookieJar.cs +++ b/dotnet/src/webdriver/CookieJar.cs @@ -71,7 +71,7 @@ public Cookie GetCookieNamed(string name) var rawCookie = driver.InternalExecute(DriverCommand.GetCookie, new() { { "name", name } }).Value; - return Cookie.FromDictionary(rawCookie as Dictionary); + return Cookie.FromDictionary((Dictionary)rawCookie); } private ReadOnlyCollection GetAllCookies()