From cb357bfbe879ea7d91cb6c6b2b5e003934f04392 Mon Sep 17 00:00:00 2001
From: Nikolay Borisenko <22616990+nvborisenko@users.noreply.github.com>
Date: Thu, 6 Nov 2025 21:00:20 +0300
Subject: [PATCH 01/26] First implementation
---
dotnet/src/webdriver/DriverOptions.cs | 87 ++++++++++++++++++++------
dotnet/test/common/BiDi/BiDiFixture.cs | 2 +-
2 files changed, 70 insertions(+), 19 deletions(-)
diff --git a/dotnet/src/webdriver/DriverOptions.cs b/dotnet/src/webdriver/DriverOptions.cs
index 483ceb03130a4..345eb7b40837a 100644
--- a/dotnet/src/webdriver/DriverOptions.cs
+++ b/dotnet/src/webdriver/DriverOptions.cs
@@ -26,6 +26,27 @@
namespace OpenQA.Selenium;
+public abstract record UnhandledPromptBehaviorOption
+{
+ public static implicit operator UnhandledPromptBehaviorOption(UnhandledPromptBehavior? value)
+ => new UnhandledPromptBehaviorSingleOption(value);
+}
+
+public sealed record UnhandledPromptBehaviorSingleOption(UnhandledPromptBehavior? Value) : UnhandledPromptBehaviorOption;
+
+public sealed record UnhandledPromptBehaviorMultiOption : UnhandledPromptBehaviorOption
+{
+ public UnhandledPromptBehavior? Alert { get; set; }
+
+ public UnhandledPromptBehavior? Confirm { get; set; }
+
+ public UnhandledPromptBehavior? Prompt { get; set; }
+
+ public UnhandledPromptBehavior? BeforeUnload { get; set; }
+
+ public UnhandledPromptBehavior? Default { get; set; }
+}
+
///
/// Specifies the behavior of handling unexpected alerts in the IE driver.
///
@@ -164,7 +185,7 @@ protected DriverOptions()
/// Gets or sets the value for describing how unexpected alerts are to be handled in the browser.
/// Defaults to .
///
- public UnhandledPromptBehavior UnhandledPromptBehavior { get; set; } = UnhandledPromptBehavior.Default;
+ public UnhandledPromptBehaviorOption? UnhandledPromptBehavior { get; set; }
///
/// Gets or sets the value for describing how the browser is to wait for pages to load in the browser.
@@ -303,7 +324,7 @@ public virtual DriverOptionsMergeResult GetMergeResult(DriverOptions other)
return result;
}
- if (this.UnhandledPromptBehavior != UnhandledPromptBehavior.Default && other.UnhandledPromptBehavior != UnhandledPromptBehavior.Default)
+ if (this.UnhandledPromptBehavior is not null && other.UnhandledPromptBehavior is not null)
{
result.IsMergeConflict = true;
result.MergeConflictOptionName = "UnhandledPromptBehavior";
@@ -508,29 +529,59 @@ protected IWritableCapabilities GenerateDesiredCapabilities(bool isSpecification
capabilities.SetCapability(CapabilityType.PageLoadStrategy, pageLoadStrategySetting);
}
- if (this.UnhandledPromptBehavior != UnhandledPromptBehavior.Default)
+ [return: NotNullIfNotNull(nameof(behavior))]
+ static string? UnhandledPromptBehaviorToString(UnhandledPromptBehavior? behavior) => behavior switch
{
- string unhandledPropmtBehaviorSetting = "ignore";
- switch (this.UnhandledPromptBehavior)
+ Selenium.UnhandledPromptBehavior.Ignore => "ignore",
+ Selenium.UnhandledPromptBehavior.Accept => "accept",
+ Selenium.UnhandledPromptBehavior.Dismiss => "dismiss",
+ Selenium.UnhandledPromptBehavior.AcceptAndNotify => "accept and notify",
+ Selenium.UnhandledPromptBehavior.DismissAndNotify => "dismiss and notify",
+ _ => null
+ };
+
+ if (this.UnhandledPromptBehavior is UnhandledPromptBehaviorSingleOption singleOption)
+ {
+ var stringValue = UnhandledPromptBehaviorToString(singleOption.Value);
+
+ if (stringValue is not null)
{
- case UnhandledPromptBehavior.Accept:
- unhandledPropmtBehaviorSetting = "accept";
- break;
+ capabilities.SetCapability(CapabilityType.UnhandledPromptBehavior, stringValue);
+ }
+ }
+ else if (this.UnhandledPromptBehavior is UnhandledPromptBehaviorMultiOption multiOption)
+ {
+ Dictionary multiOptionDictionary = [];
- case UnhandledPromptBehavior.Dismiss:
- unhandledPropmtBehaviorSetting = "dismiss";
- break;
+ if (multiOption.Alert is not null)
+ {
+ multiOptionDictionary["alert"] = UnhandledPromptBehaviorToString(multiOption.Alert);
+ }
- case UnhandledPromptBehavior.AcceptAndNotify:
- unhandledPropmtBehaviorSetting = "accept and notify";
- break;
+ if (multiOption.Confirm is not null)
+ {
+ multiOptionDictionary["confirm"] = UnhandledPromptBehaviorToString(multiOption.Confirm);
+ }
- case UnhandledPromptBehavior.DismissAndNotify:
- unhandledPropmtBehaviorSetting = "dismiss and notify";
- break;
+ if (multiOption.Prompt is not null)
+ {
+ multiOptionDictionary["prompt"] = UnhandledPromptBehaviorToString(multiOption.Prompt);
}
- capabilities.SetCapability(CapabilityType.UnhandledPromptBehavior, unhandledPropmtBehaviorSetting);
+ if (multiOption.BeforeUnload is not null)
+ {
+ multiOptionDictionary["beforeUnload"] = UnhandledPromptBehaviorToString(multiOption.BeforeUnload);
+ }
+
+ if (multiOption.Default is not null)
+ {
+ multiOptionDictionary["default"] = UnhandledPromptBehaviorToString(multiOption.Default);
+ }
+
+ if (multiOptionDictionary.Count != 0)
+ {
+ capabilities.SetCapability(CapabilityType.UnhandledPromptBehavior, multiOptionDictionary);
+ }
}
if (this.Proxy != null)
diff --git a/dotnet/test/common/BiDi/BiDiFixture.cs b/dotnet/test/common/BiDi/BiDiFixture.cs
index 88fe223a71d1c..72b69b10795b8 100644
--- a/dotnet/test/common/BiDi/BiDiFixture.cs
+++ b/dotnet/test/common/BiDi/BiDiFixture.cs
@@ -39,7 +39,7 @@ public async Task BiDiSetUp()
var options = new BiDiEnabledDriverOptions()
{
UseWebSocketUrl = true,
- UnhandledPromptBehavior = UnhandledPromptBehavior.Ignore,
+ UnhandledPromptBehavior = new UnhandledPromptBehaviorMultiOption() { Default = UnhandledPromptBehavior.Ignore },
};
driver = EnvironmentManager.Instance.CreateDriverInstance(options);
From 5a2cdd834c4fb260d8ab188fab1879d37ede9d92 Mon Sep 17 00:00:00 2001
From: Nikolay Borisenko <22616990+nvborisenko@users.noreply.github.com>
Date: Thu, 6 Nov 2025 21:05:20 +0300
Subject: [PATCH 02/26] Don't change tests to emphasize backward compatibility
---
dotnet/test/common/BiDi/BiDiFixture.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dotnet/test/common/BiDi/BiDiFixture.cs b/dotnet/test/common/BiDi/BiDiFixture.cs
index 72b69b10795b8..88fe223a71d1c 100644
--- a/dotnet/test/common/BiDi/BiDiFixture.cs
+++ b/dotnet/test/common/BiDi/BiDiFixture.cs
@@ -39,7 +39,7 @@ public async Task BiDiSetUp()
var options = new BiDiEnabledDriverOptions()
{
UseWebSocketUrl = true,
- UnhandledPromptBehavior = new UnhandledPromptBehaviorMultiOption() { Default = UnhandledPromptBehavior.Ignore },
+ UnhandledPromptBehavior = UnhandledPromptBehavior.Ignore,
};
driver = EnvironmentManager.Instance.CreateDriverInstance(options);
From 5c53619ab1da824593e594f8b97b8696863a2e41 Mon Sep 17 00:00:00 2001
From: Nikolay Borisenko <22616990+nvborisenko@users.noreply.github.com>
Date: Thu, 6 Nov 2025 21:12:53 +0300
Subject: [PATCH 03/26] Static factory?
---
dotnet/src/webdriver/DriverOptions.cs | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/dotnet/src/webdriver/DriverOptions.cs b/dotnet/src/webdriver/DriverOptions.cs
index 345eb7b40837a..56518ef6f1008 100644
--- a/dotnet/src/webdriver/DriverOptions.cs
+++ b/dotnet/src/webdriver/DriverOptions.cs
@@ -29,7 +29,17 @@ namespace OpenQA.Selenium;
public abstract record UnhandledPromptBehaviorOption
{
public static implicit operator UnhandledPromptBehaviorOption(UnhandledPromptBehavior? value)
+ => Single(value);
+
+ public static UnhandledPromptBehaviorOption Single(UnhandledPromptBehavior? value)
=> new UnhandledPromptBehaviorSingleOption(value);
+
+ public static UnhandledPromptBehaviorOption Multi(UnhandledPromptBehavior? alert = null,
+ UnhandledPromptBehavior? confirm = null,
+ UnhandledPromptBehavior? prompt = null,
+ UnhandledPromptBehavior? beforeUnload = null,
+ UnhandledPromptBehavior? @default = null)
+ => new UnhandledPromptBehaviorMultiOption() with { Alert = alert, Confirm = confirm, Prompt = prompt, BeforeUnload = beforeUnload, Default = @default };
}
public sealed record UnhandledPromptBehaviorSingleOption(UnhandledPromptBehavior? Value) : UnhandledPromptBehaviorOption;
From fc98a7829d422a1f52d6364d31f3f9079e5088b0 Mon Sep 17 00:00:00 2001
From: Nikolay Borisenko <22616990+nvborisenko@users.noreply.github.com>
Date: Thu, 6 Nov 2025 21:53:06 +0300
Subject: [PATCH 04/26] Throw exception if enum is not branched
---
dotnet/src/webdriver/DriverOptions.cs | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/dotnet/src/webdriver/DriverOptions.cs b/dotnet/src/webdriver/DriverOptions.cs
index 56518ef6f1008..4688281491ade 100644
--- a/dotnet/src/webdriver/DriverOptions.cs
+++ b/dotnet/src/webdriver/DriverOptions.cs
@@ -539,15 +539,14 @@ protected IWritableCapabilities GenerateDesiredCapabilities(bool isSpecification
capabilities.SetCapability(CapabilityType.PageLoadStrategy, pageLoadStrategySetting);
}
- [return: NotNullIfNotNull(nameof(behavior))]
- static string? UnhandledPromptBehaviorToString(UnhandledPromptBehavior? behavior) => behavior switch
+ static string UnhandledPromptBehaviorToString(UnhandledPromptBehavior? behavior) => behavior switch
{
Selenium.UnhandledPromptBehavior.Ignore => "ignore",
Selenium.UnhandledPromptBehavior.Accept => "accept",
Selenium.UnhandledPromptBehavior.Dismiss => "dismiss",
Selenium.UnhandledPromptBehavior.AcceptAndNotify => "accept and notify",
Selenium.UnhandledPromptBehavior.DismissAndNotify => "dismiss and notify",
- _ => null
+ _ => throw new WebDriverException($"'{behavior}' unhandled prompt behavior value is not recognized."),
};
if (this.UnhandledPromptBehavior is UnhandledPromptBehaviorSingleOption singleOption)
From 75fc654173edb19b78a70dbcf8e262639d9a1431 Mon Sep 17 00:00:00 2001
From: Nikolay Borisenko <22616990+nvborisenko@users.noreply.github.com>
Date: Thu, 6 Nov 2025 21:55:23 +0300
Subject: [PATCH 05/26] Revert "Throw exception if enum is not branched"
This reverts commit fc98a7829d422a1f52d6364d31f3f9079e5088b0.
---
dotnet/src/webdriver/DriverOptions.cs | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/dotnet/src/webdriver/DriverOptions.cs b/dotnet/src/webdriver/DriverOptions.cs
index 4688281491ade..56518ef6f1008 100644
--- a/dotnet/src/webdriver/DriverOptions.cs
+++ b/dotnet/src/webdriver/DriverOptions.cs
@@ -539,14 +539,15 @@ protected IWritableCapabilities GenerateDesiredCapabilities(bool isSpecification
capabilities.SetCapability(CapabilityType.PageLoadStrategy, pageLoadStrategySetting);
}
- static string UnhandledPromptBehaviorToString(UnhandledPromptBehavior? behavior) => behavior switch
+ [return: NotNullIfNotNull(nameof(behavior))]
+ static string? UnhandledPromptBehaviorToString(UnhandledPromptBehavior? behavior) => behavior switch
{
Selenium.UnhandledPromptBehavior.Ignore => "ignore",
Selenium.UnhandledPromptBehavior.Accept => "accept",
Selenium.UnhandledPromptBehavior.Dismiss => "dismiss",
Selenium.UnhandledPromptBehavior.AcceptAndNotify => "accept and notify",
Selenium.UnhandledPromptBehavior.DismissAndNotify => "dismiss and notify",
- _ => throw new WebDriverException($"'{behavior}' unhandled prompt behavior value is not recognized."),
+ _ => null
};
if (this.UnhandledPromptBehavior is UnhandledPromptBehaviorSingleOption singleOption)
From 50275d2f1b30b7e40ebfc4b6dd472e66ce350ce8 Mon Sep 17 00:00:00 2001
From: Nikolay Borisenko <22616990+nvborisenko@users.noreply.github.com>
Date: Thu, 6 Nov 2025 22:33:52 +0300
Subject: [PATCH 06/26] Throw exception if enum is not branched
---
dotnet/src/webdriver/DriverOptions.cs | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/dotnet/src/webdriver/DriverOptions.cs b/dotnet/src/webdriver/DriverOptions.cs
index 56518ef6f1008..e52a79a1eadae 100644
--- a/dotnet/src/webdriver/DriverOptions.cs
+++ b/dotnet/src/webdriver/DriverOptions.cs
@@ -547,7 +547,8 @@ protected IWritableCapabilities GenerateDesiredCapabilities(bool isSpecification
Selenium.UnhandledPromptBehavior.Dismiss => "dismiss",
Selenium.UnhandledPromptBehavior.AcceptAndNotify => "accept and notify",
Selenium.UnhandledPromptBehavior.DismissAndNotify => "dismiss and notify",
- _ => null
+ null or Selenium.UnhandledPromptBehavior.Default => null,
+ _ => throw new ArgumentOutOfRangeException(nameof(behavior), $"UnhandledPromptBehavior value '{behavior}' is not recognized."),
};
if (this.UnhandledPromptBehavior is UnhandledPromptBehaviorSingleOption singleOption)
From 9accc2bd124a802f30a89f744df6474c7ec14556 Mon Sep 17 00:00:00 2001
From: Nikolay Borisenko <22616990+nvborisenko@users.noreply.github.com>
Date: Fri, 7 Nov 2025 22:00:07 +0300
Subject: [PATCH 07/26] Non nullable enum values
---
dotnet/src/webdriver/DriverOptions.cs | 45 +++++++++++----------------
1 file changed, 18 insertions(+), 27 deletions(-)
diff --git a/dotnet/src/webdriver/DriverOptions.cs b/dotnet/src/webdriver/DriverOptions.cs
index e52a79a1eadae..4e14a6f1a6c13 100644
--- a/dotnet/src/webdriver/DriverOptions.cs
+++ b/dotnet/src/webdriver/DriverOptions.cs
@@ -28,33 +28,29 @@ namespace OpenQA.Selenium;
public abstract record UnhandledPromptBehaviorOption
{
- public static implicit operator UnhandledPromptBehaviorOption(UnhandledPromptBehavior? value)
+ public static implicit operator UnhandledPromptBehaviorOption(UnhandledPromptBehavior value)
=> Single(value);
- public static UnhandledPromptBehaviorOption Single(UnhandledPromptBehavior? value)
+ public static UnhandledPromptBehaviorOption Single(UnhandledPromptBehavior value)
=> new UnhandledPromptBehaviorSingleOption(value);
- public static UnhandledPromptBehaviorOption Multi(UnhandledPromptBehavior? alert = null,
- UnhandledPromptBehavior? confirm = null,
- UnhandledPromptBehavior? prompt = null,
- UnhandledPromptBehavior? beforeUnload = null,
- UnhandledPromptBehavior? @default = null)
- => new UnhandledPromptBehaviorMultiOption() with { Alert = alert, Confirm = confirm, Prompt = prompt, BeforeUnload = beforeUnload, Default = @default };
+ public static UnhandledPromptBehaviorOption Multi()
+ => new UnhandledPromptBehaviorMultiOption();
}
-public sealed record UnhandledPromptBehaviorSingleOption(UnhandledPromptBehavior? Value) : UnhandledPromptBehaviorOption;
+public sealed record UnhandledPromptBehaviorSingleOption(UnhandledPromptBehavior Value) : UnhandledPromptBehaviorOption;
public sealed record UnhandledPromptBehaviorMultiOption : UnhandledPromptBehaviorOption
{
- public UnhandledPromptBehavior? Alert { get; set; }
+ public UnhandledPromptBehavior Alert { get; set; } = UnhandledPromptBehavior.Default;
- public UnhandledPromptBehavior? Confirm { get; set; }
+ public UnhandledPromptBehavior Confirm { get; set; } = UnhandledPromptBehavior.Default;
- public UnhandledPromptBehavior? Prompt { get; set; }
+ public UnhandledPromptBehavior Prompt { get; set; } = UnhandledPromptBehavior.Default;
- public UnhandledPromptBehavior? BeforeUnload { get; set; }
+ public UnhandledPromptBehavior BeforeUnload { get; set; } = UnhandledPromptBehavior.Default;
- public UnhandledPromptBehavior? Default { get; set; }
+ public UnhandledPromptBehavior Default { get; set; } = UnhandledPromptBehavior.Default;
}
///
@@ -539,52 +535,47 @@ protected IWritableCapabilities GenerateDesiredCapabilities(bool isSpecification
capabilities.SetCapability(CapabilityType.PageLoadStrategy, pageLoadStrategySetting);
}
- [return: NotNullIfNotNull(nameof(behavior))]
- static string? UnhandledPromptBehaviorToString(UnhandledPromptBehavior? behavior) => behavior switch
+ static string UnhandledPromptBehaviorToString(UnhandledPromptBehavior behavior) => behavior switch
{
Selenium.UnhandledPromptBehavior.Ignore => "ignore",
Selenium.UnhandledPromptBehavior.Accept => "accept",
Selenium.UnhandledPromptBehavior.Dismiss => "dismiss",
Selenium.UnhandledPromptBehavior.AcceptAndNotify => "accept and notify",
Selenium.UnhandledPromptBehavior.DismissAndNotify => "dismiss and notify",
- null or Selenium.UnhandledPromptBehavior.Default => null,
_ => throw new ArgumentOutOfRangeException(nameof(behavior), $"UnhandledPromptBehavior value '{behavior}' is not recognized."),
};
- if (this.UnhandledPromptBehavior is UnhandledPromptBehaviorSingleOption singleOption)
+ if (this.UnhandledPromptBehavior is UnhandledPromptBehaviorSingleOption singleOption && singleOption.Value != Selenium.UnhandledPromptBehavior.Default)
{
var stringValue = UnhandledPromptBehaviorToString(singleOption.Value);
- if (stringValue is not null)
- {
- capabilities.SetCapability(CapabilityType.UnhandledPromptBehavior, stringValue);
- }
+ capabilities.SetCapability(CapabilityType.UnhandledPromptBehavior, stringValue);
}
else if (this.UnhandledPromptBehavior is UnhandledPromptBehaviorMultiOption multiOption)
{
Dictionary multiOptionDictionary = [];
- if (multiOption.Alert is not null)
+ if (multiOption.Alert is not Selenium.UnhandledPromptBehavior.Default)
{
multiOptionDictionary["alert"] = UnhandledPromptBehaviorToString(multiOption.Alert);
}
- if (multiOption.Confirm is not null)
+ if (multiOption.Confirm is not Selenium.UnhandledPromptBehavior.Default)
{
multiOptionDictionary["confirm"] = UnhandledPromptBehaviorToString(multiOption.Confirm);
}
- if (multiOption.Prompt is not null)
+ if (multiOption.Prompt is not Selenium.UnhandledPromptBehavior.Default)
{
multiOptionDictionary["prompt"] = UnhandledPromptBehaviorToString(multiOption.Prompt);
}
- if (multiOption.BeforeUnload is not null)
+ if (multiOption.BeforeUnload is not Selenium.UnhandledPromptBehavior.Default)
{
multiOptionDictionary["beforeUnload"] = UnhandledPromptBehaviorToString(multiOption.BeforeUnload);
}
- if (multiOption.Default is not null)
+ if (multiOption.Default is not Selenium.UnhandledPromptBehavior.Default)
{
multiOptionDictionary["default"] = UnhandledPromptBehaviorToString(multiOption.Default);
}
From 727a5b3c10da51bd81f71f4215c08ff03841eff1 Mon Sep 17 00:00:00 2001
From: Nikolay Borisenko <22616990+nvborisenko@users.noreply.github.com>
Date: Wed, 26 Nov 2025 22:51:17 +0300
Subject: [PATCH 08/26] Move to new UnhandledPromptBehaviorOption file
---
dotnet/src/webdriver/DriverOptions.cs | 65 --------------
.../UnhandledPromptBehaviorOption.cs | 85 +++++++++++++++++++
2 files changed, 85 insertions(+), 65 deletions(-)
create mode 100644 dotnet/src/webdriver/UnhandledPromptBehaviorOption.cs
diff --git a/dotnet/src/webdriver/DriverOptions.cs b/dotnet/src/webdriver/DriverOptions.cs
index 4e14a6f1a6c13..555a78d7a3a51 100644
--- a/dotnet/src/webdriver/DriverOptions.cs
+++ b/dotnet/src/webdriver/DriverOptions.cs
@@ -26,71 +26,6 @@
namespace OpenQA.Selenium;
-public abstract record UnhandledPromptBehaviorOption
-{
- public static implicit operator UnhandledPromptBehaviorOption(UnhandledPromptBehavior value)
- => Single(value);
-
- public static UnhandledPromptBehaviorOption Single(UnhandledPromptBehavior value)
- => new UnhandledPromptBehaviorSingleOption(value);
-
- public static UnhandledPromptBehaviorOption Multi()
- => new UnhandledPromptBehaviorMultiOption();
-}
-
-public sealed record UnhandledPromptBehaviorSingleOption(UnhandledPromptBehavior Value) : UnhandledPromptBehaviorOption;
-
-public sealed record UnhandledPromptBehaviorMultiOption : UnhandledPromptBehaviorOption
-{
- public UnhandledPromptBehavior Alert { get; set; } = UnhandledPromptBehavior.Default;
-
- public UnhandledPromptBehavior Confirm { get; set; } = UnhandledPromptBehavior.Default;
-
- public UnhandledPromptBehavior Prompt { get; set; } = UnhandledPromptBehavior.Default;
-
- public UnhandledPromptBehavior BeforeUnload { get; set; } = UnhandledPromptBehavior.Default;
-
- public UnhandledPromptBehavior Default { get; set; } = UnhandledPromptBehavior.Default;
-}
-
-///
-/// Specifies the behavior of handling unexpected alerts in the IE driver.
-///
-public enum UnhandledPromptBehavior
-{
- ///
- /// Indicates the behavior is not set.
- ///
- Default,
-
- ///
- /// Ignore unexpected alerts, such that the user must handle them.
- ///
- Ignore,
-
- ///
- /// Accept unexpected alerts.
- ///
- Accept,
-
- ///
- /// Dismiss unexpected alerts.
- ///
- Dismiss,
-
- ///
- /// Accepts unexpected alerts and notifies the user that the alert has
- /// been accepted by throwing an
- ///
- AcceptAndNotify,
-
- ///
- /// Dismisses unexpected alerts and notifies the user that the alert has
- /// been dismissed by throwing an
- ///
- DismissAndNotify
-}
-
///
/// Specifies the behavior of waiting for page loads in the driver.
///
diff --git a/dotnet/src/webdriver/UnhandledPromptBehaviorOption.cs b/dotnet/src/webdriver/UnhandledPromptBehaviorOption.cs
new file mode 100644
index 0000000000000..8366ef08966e5
--- /dev/null
+++ b/dotnet/src/webdriver/UnhandledPromptBehaviorOption.cs
@@ -0,0 +1,85 @@
+//
+// 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.
+//
+
+namespace OpenQA.Selenium;
+
+public abstract record UnhandledPromptBehaviorOption
+{
+ public static implicit operator UnhandledPromptBehaviorOption(UnhandledPromptBehavior value)
+ => Single(value);
+
+ public static UnhandledPromptBehaviorOption Single(UnhandledPromptBehavior value)
+ => new UnhandledPromptBehaviorSingleOption(value);
+
+ public static UnhandledPromptBehaviorOption Multi()
+ => new UnhandledPromptBehaviorMultiOption();
+}
+
+public sealed record UnhandledPromptBehaviorSingleOption(UnhandledPromptBehavior Value) : UnhandledPromptBehaviorOption;
+
+public sealed record UnhandledPromptBehaviorMultiOption : UnhandledPromptBehaviorOption
+{
+ public UnhandledPromptBehavior Alert { get; set; } = UnhandledPromptBehavior.Default;
+
+ public UnhandledPromptBehavior Confirm { get; set; } = UnhandledPromptBehavior.Default;
+
+ public UnhandledPromptBehavior Prompt { get; set; } = UnhandledPromptBehavior.Default;
+
+ public UnhandledPromptBehavior BeforeUnload { get; set; } = UnhandledPromptBehavior.Default;
+
+ public UnhandledPromptBehavior Default { get; set; } = UnhandledPromptBehavior.Default;
+}
+
+///
+/// Specifies the behavior of handling unexpected alerts in the IE driver.
+///
+public enum UnhandledPromptBehavior
+{
+ ///
+ /// Indicates the behavior is not set.
+ ///
+ Default,
+
+ ///
+ /// Ignore unexpected alerts, such that the user must handle them.
+ ///
+ Ignore,
+
+ ///
+ /// Accept unexpected alerts.
+ ///
+ Accept,
+
+ ///
+ /// Dismiss unexpected alerts.
+ ///
+ Dismiss,
+
+ ///
+ /// Accepts unexpected alerts and notifies the user that the alert has
+ /// been accepted by throwing an
+ ///
+ AcceptAndNotify,
+
+ ///
+ /// Dismisses unexpected alerts and notifies the user that the alert has
+ /// been dismissed by throwing an
+ ///
+ DismissAndNotify
+}
From 96cd5cd8592d623509a1da2f5a8773de87868752 Mon Sep 17 00:00:00 2001
From: Nikolay Borisenko <22616990+nvborisenko@users.noreply.github.com>
Date: Wed, 26 Nov 2025 22:58:53 +0300
Subject: [PATCH 09/26] Docs
---
.../UnhandledPromptBehaviorOption.cs | 56 +++++++++++++++++++
1 file changed, 56 insertions(+)
diff --git a/dotnet/src/webdriver/UnhandledPromptBehaviorOption.cs b/dotnet/src/webdriver/UnhandledPromptBehaviorOption.cs
index 8366ef08966e5..fa4ebc318a08b 100644
--- a/dotnet/src/webdriver/UnhandledPromptBehaviorOption.cs
+++ b/dotnet/src/webdriver/UnhandledPromptBehaviorOption.cs
@@ -19,30 +19,86 @@
namespace OpenQA.Selenium;
+///
+/// Represents a configuration option that determines how unhandled prompts are managed during automated browser
+/// interactions.
+///
+/// Use this type to specify whether a single unhandled prompt behavior or multiple behaviors should be
+/// applied. The static methods provide convenient ways to create either a single-behavior or multi-behavior option.
+/// This abstraction is typically used in scenarios where browser automation frameworks need to control the handling of
+/// unexpected dialogs or prompts.
public abstract record UnhandledPromptBehaviorOption
{
+ ///
+ /// Converts a value of type to an instance.
+ ///
+ /// The value to convert.
public static implicit operator UnhandledPromptBehaviorOption(UnhandledPromptBehavior value)
=> Single(value);
+ ///
+ /// Creates an representing a single value.
+ ///
+ /// The to apply for all prompt types.
+ /// An wrapping the provided behavior.
public static UnhandledPromptBehaviorOption Single(UnhandledPromptBehavior value)
=> new UnhandledPromptBehaviorSingleOption(value);
+ ///
+ /// Creates an allowing individual values per prompt type.
+ ///
+ /// An with per-prompt configurable behaviors.
public static UnhandledPromptBehaviorOption Multi()
=> new UnhandledPromptBehaviorMultiOption();
}
+///
+/// Represents an option that specifies a single unhandled prompt behavior to use when interacting with browser dialogs.
+///
+/// The unhandled prompt behavior to apply. Specifies how unexpected browser prompts are handled during automation.
public sealed record UnhandledPromptBehaviorSingleOption(UnhandledPromptBehavior Value) : UnhandledPromptBehaviorOption;
+///
+/// Represents a set of options that specify how unhandled browser prompts are handled for different prompt types.
+///
+/// Use this class to configure distinct behaviors for alert, confirm, prompt, and beforeunload dialogs
+/// encountered during browser automation. Each property allows you to control the response to a specific type of
+/// unhandled prompt, enabling fine-grained handling beyond a single global setting.
public sealed record UnhandledPromptBehaviorMultiOption : UnhandledPromptBehaviorOption
{
+ ///
+ /// Gets or sets the behavior to use when an unexpected alert is encountered during automation.
+ ///
public UnhandledPromptBehavior Alert { get; set; } = UnhandledPromptBehavior.Default;
+ ///
+ /// Gets or sets the behavior to use when a confirmation prompt is encountered.
+ ///
+ /// Set this property to specify how the system should respond to confirmation dialogs, such as
+ /// JavaScript confirm boxes, during automated operations. The default value is , which applies the standard handling defined by the
+ /// environment.
public UnhandledPromptBehavior Confirm { get; set; } = UnhandledPromptBehavior.Default;
+ ///
+ /// Gets or sets the behavior to use when an unexpected prompt is encountered during automation.
+ ///
+ /// Set this property to control how the system responds to unhandled prompts, such as alerts or
+ /// confirmation dialogs, that appear unexpectedly. The default behavior is determined by the value of
+ /// .
public UnhandledPromptBehavior Prompt { get; set; } = UnhandledPromptBehavior.Default;
+ ///
+ /// Gets or sets the behavior to use when an unexpected beforeunload dialog is encountered.
+ ///
+ /// Use this property to specify how the application should respond to beforeunload dialogs that
+ /// appear unexpectedly during automated browser interactions. This setting determines whether such dialogs are
+ /// automatically accepted, dismissed, or cause an error.
public UnhandledPromptBehavior BeforeUnload { get; set; } = UnhandledPromptBehavior.Default;
+ ///
+ /// Gets or sets the default behavior to use when an unexpected browser prompt is encountered.
+ ///
public UnhandledPromptBehavior Default { get; set; } = UnhandledPromptBehavior.Default;
}
From 83b5218dcf01782ff3f23c0c74603679cf38e339 Mon Sep 17 00:00:00 2001
From: Nikolay Borisenko <22616990+nvborisenko@users.noreply.github.com>
Date: Wed, 26 Nov 2025 23:06:58 +0300
Subject: [PATCH 10/26] Docs for possible types
---
.../webdriver/UnhandledPromptBehaviorOption.cs | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)
diff --git a/dotnet/src/webdriver/UnhandledPromptBehaviorOption.cs b/dotnet/src/webdriver/UnhandledPromptBehaviorOption.cs
index fa4ebc318a08b..451b826b85d93 100644
--- a/dotnet/src/webdriver/UnhandledPromptBehaviorOption.cs
+++ b/dotnet/src/webdriver/UnhandledPromptBehaviorOption.cs
@@ -23,10 +23,19 @@ namespace OpenQA.Selenium;
/// Represents a configuration option that determines how unhandled prompts are managed during automated browser
/// interactions.
///
-/// Use this type to specify whether a single unhandled prompt behavior or multiple behaviors should be
-/// applied. The static methods provide convenient ways to create either a single-behavior or multi-behavior option.
+///
+/// Use this type to specify whether a single unhandled prompt behavior or multiple behaviors should be applied.
+/// The static methods provide convenient ways to create either a single-behavior or multi-behavior option.
/// This abstraction is typically used in scenarios where browser automation frameworks need to control the handling of
-/// unexpected dialogs or prompts.
+/// unexpected dialogs or prompts.
+///
+/// Derived types:
+///
+/// - - Wraps a single value applied to all prompt types. Create via the implicit conversion from or by calling .
+/// - - Allows configuring per-prompt behaviors (Alert, Confirm, Prompt, BeforeUnload, Default). Create via .
+///
+///
+///
public abstract record UnhandledPromptBehaviorOption
{
///
From f5e5845d2fa1aac6c82938f0b9dfa664e86181c1 Mon Sep 17 00:00:00 2001
From: Nikolay Borisenko <22616990+nvborisenko@users.noreply.github.com>
Date: Wed, 26 Nov 2025 23:08:36 +0300
Subject: [PATCH 11/26] Clear as options
---
dotnet/src/webdriver/UnhandledPromptBehaviorOption.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dotnet/src/webdriver/UnhandledPromptBehaviorOption.cs b/dotnet/src/webdriver/UnhandledPromptBehaviorOption.cs
index 451b826b85d93..7e0dc35988243 100644
--- a/dotnet/src/webdriver/UnhandledPromptBehaviorOption.cs
+++ b/dotnet/src/webdriver/UnhandledPromptBehaviorOption.cs
@@ -29,7 +29,7 @@ namespace OpenQA.Selenium;
/// This abstraction is typically used in scenarios where browser automation frameworks need to control the handling of
/// unexpected dialogs or prompts.
///
-/// Derived types:
+/// Available options:
///
/// - - Wraps a single value applied to all prompt types. Create via the implicit conversion from or by calling .
/// - - Allows configuring per-prompt behaviors (Alert, Confirm, Prompt, BeforeUnload, Default). Create via .
From baf2939b0c972cd22cdcdba413208fe780f863ff Mon Sep 17 00:00:00 2001
From: Nikolay Borisenko <22616990+nvborisenko@users.noreply.github.com>
Date: Tue, 9 Dec 2025 17:48:39 +0300
Subject: [PATCH 12/26] Fix static factory
---
.../src/webdriver/UnhandledPromptBehaviorOption.cs | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/dotnet/src/webdriver/UnhandledPromptBehaviorOption.cs b/dotnet/src/webdriver/UnhandledPromptBehaviorOption.cs
index 7e0dc35988243..11ae1cde78188 100644
--- a/dotnet/src/webdriver/UnhandledPromptBehaviorOption.cs
+++ b/dotnet/src/webdriver/UnhandledPromptBehaviorOption.cs
@@ -46,18 +46,18 @@ public static implicit operator UnhandledPromptBehaviorOption(UnhandledPromptBeh
=> Single(value);
///
- /// Creates an representing a single value.
+ /// Creates an representing a single value.
///
/// The to apply for all prompt types.
- /// An wrapping the provided behavior.
- public static UnhandledPromptBehaviorOption Single(UnhandledPromptBehavior value)
+ /// An wrapping the provided behavior.
+ public static UnhandledPromptBehaviorSingleOption Single(UnhandledPromptBehavior value)
=> new UnhandledPromptBehaviorSingleOption(value);
///
- /// Creates an allowing individual values per prompt type.
+ /// Creates an allowing individual values per prompt type.
///
- /// An with per-prompt configurable behaviors.
- public static UnhandledPromptBehaviorOption Multi()
+ /// An with per-prompt configurable behaviors.
+ public static UnhandledPromptBehaviorMultiOption Multi()
=> new UnhandledPromptBehaviorMultiOption();
}
From bfd55e9d2d116efa9c48d73f6a954b4123f83e9c Mon Sep 17 00:00:00 2001
From: Nikolay Borisenko <22616990+nvborisenko@users.noreply.github.com>
Date: Tue, 9 Dec 2025 17:59:36 +0300
Subject: [PATCH 13/26] Consider the property in MergeResult
---
dotnet/src/webdriver/DriverOptions.cs | 4 ++--
dotnet/src/webdriver/UnhandledPromptBehaviorOption.cs | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/dotnet/src/webdriver/DriverOptions.cs b/dotnet/src/webdriver/DriverOptions.cs
index 555a78d7a3a51..2721acdfc42dd 100644
--- a/dotnet/src/webdriver/DriverOptions.cs
+++ b/dotnet/src/webdriver/DriverOptions.cs
@@ -126,7 +126,7 @@ protected DriverOptions()
/// Gets or sets the value for describing how unexpected alerts are to be handled in the browser.
/// Defaults to .
///
- public UnhandledPromptBehaviorOption? UnhandledPromptBehavior { get; set; }
+ public UnhandledPromptBehaviorOption? UnhandledPromptBehavior { get; set; } = Selenium.UnhandledPromptBehavior.Default;
///
/// Gets or sets the value for describing how the browser is to wait for pages to load in the browser.
@@ -265,7 +265,7 @@ public virtual DriverOptionsMergeResult GetMergeResult(DriverOptions other)
return result;
}
- if (this.UnhandledPromptBehavior is not null && other.UnhandledPromptBehavior is not null)
+ if (this.UnhandledPromptBehavior != other.UnhandledPromptBehavior)
{
result.IsMergeConflict = true;
result.MergeConflictOptionName = "UnhandledPromptBehavior";
diff --git a/dotnet/src/webdriver/UnhandledPromptBehaviorOption.cs b/dotnet/src/webdriver/UnhandledPromptBehaviorOption.cs
index 11ae1cde78188..e8f7b8fd405c1 100644
--- a/dotnet/src/webdriver/UnhandledPromptBehaviorOption.cs
+++ b/dotnet/src/webdriver/UnhandledPromptBehaviorOption.cs
@@ -51,14 +51,14 @@ public static implicit operator UnhandledPromptBehaviorOption(UnhandledPromptBeh
/// The to apply for all prompt types.
/// An wrapping the provided behavior.
public static UnhandledPromptBehaviorSingleOption Single(UnhandledPromptBehavior value)
- => new UnhandledPromptBehaviorSingleOption(value);
+ => new(value);
///
/// Creates an allowing individual values per prompt type.
///
/// An with per-prompt configurable behaviors.
public static UnhandledPromptBehaviorMultiOption Multi()
- => new UnhandledPromptBehaviorMultiOption();
+ => new();
}
///
From c94cc5de70472886fd297a3bc32b0cf38c0d149e Mon Sep 17 00:00:00 2001
From: Nikolay Borisenko <22616990+nvborisenko@users.noreply.github.com>
Date: Tue, 9 Dec 2025 18:45:14 +0300
Subject: [PATCH 14/26] Refactor serialization
---
dotnet/src/webdriver/DriverOptions.cs | 62 +++++--------------
.../UnhandledPromptBehaviorOption.cs | 46 ++++++++++++++
2 files changed, 60 insertions(+), 48 deletions(-)
diff --git a/dotnet/src/webdriver/DriverOptions.cs b/dotnet/src/webdriver/DriverOptions.cs
index 2721acdfc42dd..4b2f7006b2df9 100644
--- a/dotnet/src/webdriver/DriverOptions.cs
+++ b/dotnet/src/webdriver/DriverOptions.cs
@@ -470,55 +470,21 @@ protected IWritableCapabilities GenerateDesiredCapabilities(bool isSpecification
capabilities.SetCapability(CapabilityType.PageLoadStrategy, pageLoadStrategySetting);
}
- static string UnhandledPromptBehaviorToString(UnhandledPromptBehavior behavior) => behavior switch
+ switch (this.UnhandledPromptBehavior)
{
- Selenium.UnhandledPromptBehavior.Ignore => "ignore",
- Selenium.UnhandledPromptBehavior.Accept => "accept",
- Selenium.UnhandledPromptBehavior.Dismiss => "dismiss",
- Selenium.UnhandledPromptBehavior.AcceptAndNotify => "accept and notify",
- Selenium.UnhandledPromptBehavior.DismissAndNotify => "dismiss and notify",
- _ => throw new ArgumentOutOfRangeException(nameof(behavior), $"UnhandledPromptBehavior value '{behavior}' is not recognized."),
- };
-
- if (this.UnhandledPromptBehavior is UnhandledPromptBehaviorSingleOption singleOption && singleOption.Value != Selenium.UnhandledPromptBehavior.Default)
- {
- var stringValue = UnhandledPromptBehaviorToString(singleOption.Value);
-
- capabilities.SetCapability(CapabilityType.UnhandledPromptBehavior, stringValue);
- }
- else if (this.UnhandledPromptBehavior is UnhandledPromptBehaviorMultiOption multiOption)
- {
- Dictionary multiOptionDictionary = [];
-
- if (multiOption.Alert is not Selenium.UnhandledPromptBehavior.Default)
- {
- multiOptionDictionary["alert"] = UnhandledPromptBehaviorToString(multiOption.Alert);
- }
-
- if (multiOption.Confirm is not Selenium.UnhandledPromptBehavior.Default)
- {
- multiOptionDictionary["confirm"] = UnhandledPromptBehaviorToString(multiOption.Confirm);
- }
-
- if (multiOption.Prompt is not Selenium.UnhandledPromptBehavior.Default)
- {
- multiOptionDictionary["prompt"] = UnhandledPromptBehaviorToString(multiOption.Prompt);
- }
-
- if (multiOption.BeforeUnload is not Selenium.UnhandledPromptBehavior.Default)
- {
- multiOptionDictionary["beforeUnload"] = UnhandledPromptBehaviorToString(multiOption.BeforeUnload);
- }
-
- if (multiOption.Default is not Selenium.UnhandledPromptBehavior.Default)
- {
- multiOptionDictionary["default"] = UnhandledPromptBehaviorToString(multiOption.Default);
- }
-
- if (multiOptionDictionary.Count != 0)
- {
- capabilities.SetCapability(CapabilityType.UnhandledPromptBehavior, multiOptionDictionary);
- }
+ case UnhandledPromptBehaviorSingleOption singleOption:
+ if (singleOption != default)
+ {
+ var stringValue = UnhandledPromptBehaviorOption.ConvertBehaviorToString(singleOption.Value);
+ capabilities.SetCapability(CapabilityType.UnhandledPromptBehavior, stringValue);
+ }
+ break;
+ case UnhandledPromptBehaviorMultiOption multiOption:
+ if (multiOption != default)
+ {
+ capabilities.SetCapability(CapabilityType.UnhandledPromptBehavior, multiOption.ToCapabilities());
+ }
+ break;
}
if (this.Proxy != null)
diff --git a/dotnet/src/webdriver/UnhandledPromptBehaviorOption.cs b/dotnet/src/webdriver/UnhandledPromptBehaviorOption.cs
index e8f7b8fd405c1..a07f797a19c3f 100644
--- a/dotnet/src/webdriver/UnhandledPromptBehaviorOption.cs
+++ b/dotnet/src/webdriver/UnhandledPromptBehaviorOption.cs
@@ -17,6 +17,9 @@
// under the License.
//
+using System;
+using System.Collections.Generic;
+
namespace OpenQA.Selenium;
///
@@ -59,6 +62,17 @@ public static UnhandledPromptBehaviorSingleOption Single(UnhandledPromptBehavior
/// An with per-prompt configurable behaviors.
public static UnhandledPromptBehaviorMultiOption Multi()
=> new();
+
+ internal static string ConvertBehaviorToString(UnhandledPromptBehavior behavior) =>
+ behavior switch
+ {
+ UnhandledPromptBehavior.Ignore => "ignore",
+ UnhandledPromptBehavior.Accept => "accept",
+ UnhandledPromptBehavior.Dismiss => "dismiss",
+ UnhandledPromptBehavior.AcceptAndNotify => "accept and notify",
+ UnhandledPromptBehavior.DismissAndNotify => "dismiss and notify",
+ _ => throw new ArgumentOutOfRangeException(nameof(behavior), $"UnhandledPromptBehavior value '{behavior}' is not recognized."),
+ };
}
///
@@ -109,6 +123,38 @@ public sealed record UnhandledPromptBehaviorMultiOption : UnhandledPromptBehavio
/// Gets or sets the default behavior to use when an unexpected browser prompt is encountered.
///
public UnhandledPromptBehavior Default { get; set; } = UnhandledPromptBehavior.Default;
+
+ internal Dictionary ToCapabilities()
+ {
+ Dictionary capabilities = [];
+
+ if (Alert != default)
+ {
+ capabilities["alert"] = ConvertBehaviorToString(Alert);
+ }
+
+ if (Confirm != default)
+ {
+ capabilities["confirm"] = ConvertBehaviorToString(Confirm);
+ }
+
+ if (Prompt != default)
+ {
+ capabilities["prompt"] = ConvertBehaviorToString(Prompt);
+ }
+
+ if (BeforeUnload != default)
+ {
+ capabilities["beforeUnload"] = ConvertBehaviorToString(BeforeUnload);
+ }
+
+ if (Default != default)
+ {
+ capabilities["default"] = ConvertBehaviorToString(Default);
+ }
+
+ return capabilities;
+ }
}
///
From 4f609270a24248789b12d9557376e86d39aa4dc5 Mon Sep 17 00:00:00 2001
From: Nikolay Borisenko <22616990+nvborisenko@users.noreply.github.com>
Date: Tue, 9 Dec 2025 19:11:57 +0300
Subject: [PATCH 15/26] Fully delegate to ToCapabilities
---
dotnet/src/webdriver/DriverOptions.cs | 18 ++++-----------
.../UnhandledPromptBehaviorOption.cs | 22 +++++++++++++++++--
2 files changed, 24 insertions(+), 16 deletions(-)
diff --git a/dotnet/src/webdriver/DriverOptions.cs b/dotnet/src/webdriver/DriverOptions.cs
index 4b2f7006b2df9..84942ea73b22f 100644
--- a/dotnet/src/webdriver/DriverOptions.cs
+++ b/dotnet/src/webdriver/DriverOptions.cs
@@ -470,21 +470,11 @@ protected IWritableCapabilities GenerateDesiredCapabilities(bool isSpecification
capabilities.SetCapability(CapabilityType.PageLoadStrategy, pageLoadStrategySetting);
}
- switch (this.UnhandledPromptBehavior)
+ var unhandledPromptBehaviorCapability = this.UnhandledPromptBehavior?.ToCapabilities();
+
+ if (unhandledPromptBehaviorCapability != null)
{
- case UnhandledPromptBehaviorSingleOption singleOption:
- if (singleOption != default)
- {
- var stringValue = UnhandledPromptBehaviorOption.ConvertBehaviorToString(singleOption.Value);
- capabilities.SetCapability(CapabilityType.UnhandledPromptBehavior, stringValue);
- }
- break;
- case UnhandledPromptBehaviorMultiOption multiOption:
- if (multiOption != default)
- {
- capabilities.SetCapability(CapabilityType.UnhandledPromptBehavior, multiOption.ToCapabilities());
- }
- break;
+ capabilities.SetCapability(CapabilityType.UnhandledPromptBehavior, unhandledPromptBehaviorCapability);
}
if (this.Proxy != null)
diff --git a/dotnet/src/webdriver/UnhandledPromptBehaviorOption.cs b/dotnet/src/webdriver/UnhandledPromptBehaviorOption.cs
index a07f797a19c3f..29e0768fab934 100644
--- a/dotnet/src/webdriver/UnhandledPromptBehaviorOption.cs
+++ b/dotnet/src/webdriver/UnhandledPromptBehaviorOption.cs
@@ -63,6 +63,8 @@ public static UnhandledPromptBehaviorSingleOption Single(UnhandledPromptBehavior
public static UnhandledPromptBehaviorMultiOption Multi()
=> new();
+ internal abstract object? ToCapabilities();
+
internal static string ConvertBehaviorToString(UnhandledPromptBehavior behavior) =>
behavior switch
{
@@ -79,7 +81,18 @@ internal static string ConvertBehaviorToString(UnhandledPromptBehavior behavior)
/// Represents an option that specifies a single unhandled prompt behavior to use when interacting with browser dialogs.
///
/// The unhandled prompt behavior to apply. Specifies how unexpected browser prompts are handled during automation.
-public sealed record UnhandledPromptBehaviorSingleOption(UnhandledPromptBehavior Value) : UnhandledPromptBehaviorOption;
+public sealed record UnhandledPromptBehaviorSingleOption(UnhandledPromptBehavior Value) : UnhandledPromptBehaviorOption
+{
+ internal override object? ToCapabilities()
+ {
+ if (Value == UnhandledPromptBehavior.Default)
+ {
+ return null;
+ }
+
+ return ConvertBehaviorToString(Value);
+ }
+}
///
/// Represents a set of options that specify how unhandled browser prompts are handled for different prompt types.
@@ -124,8 +137,13 @@ public sealed record UnhandledPromptBehaviorMultiOption : UnhandledPromptBehavio
///
public UnhandledPromptBehavior Default { get; set; } = UnhandledPromptBehavior.Default;
- internal Dictionary ToCapabilities()
+ internal override object? ToCapabilities()
{
+ if (this == new UnhandledPromptBehaviorMultiOption())
+ {
+ return null;
+ }
+
Dictionary capabilities = [];
if (Alert != default)
From aeb98ae20008d29da9bb21d448710b121fb92ca8 Mon Sep 17 00:00:00 2001
From: Nikolay Borisenko <22616990+nvborisenko@users.noreply.github.com>
Date: Tue, 9 Dec 2025 19:53:36 +0300
Subject: [PATCH 16/26] Test
---
dotnet/test/common/AlertsTest.cs | 28 ++++++++++++++++++++++++++++
1 file changed, 28 insertions(+)
diff --git a/dotnet/test/common/AlertsTest.cs b/dotnet/test/common/AlertsTest.cs
index f2255c1964a66..f281b28af4a72 100644
--- a/dotnet/test/common/AlertsTest.cs
+++ b/dotnet/test/common/AlertsTest.cs
@@ -37,6 +37,22 @@ public void ShouldBeAbleToOverrideTheWindowAlertMethod()
driver.FindElement(By.Id("alert")).Click();
}
+ [Test]
+ public void ShouldBeAbleToDismissTheWindowAlert()
+ {
+ using var driver = EnvironmentManager.Instance.CreateDriverInstance(new CustomAlertDriverOptions
+ {
+ UnhandledPromptBehavior = new UnhandledPromptBehaviorMultiOption { Default = UnhandledPromptBehavior.Dismiss }
+ });
+
+ driver.Url = CreateAlertPage("cheese");
+
+ driver.FindElement(By.Id("alert")).Click();
+
+ // If we can perform any action again, we're good to go
+ driver.FindElement(By.Id("alert")).Click();
+ }
+
[Test]
public void ShouldAllowUsersToAcceptAnAlertManually()
{
@@ -559,4 +575,16 @@ private Func WindowHandleCountToBe(int count)
};
}
+ class CustomAlertDriverOptions : DriverOptions
+ {
+ public CustomAlertDriverOptions()
+ {
+
+ }
+
+ public override ICapabilities ToCapabilities()
+ {
+ return null;
+ }
+ }
}
From 1e53b6b31852d310bd4869a2d265083d3e235875 Mon Sep 17 00:00:00 2001
From: Nikolay Borisenko <22616990+nvborisenko@users.noreply.github.com>
Date: Thu, 23 Apr 2026 21:00:50 +0300
Subject: [PATCH 17/26] UserPromptHandler - spec defined type
---
dotnet/src/webdriver/DriverOptions.cs | 2 +-
.../UnhandledPromptBehaviorOption.cs | 214 ------------------
dotnet/src/webdriver/UserPromptHandler.cs | 201 ++++++++++++++++
dotnet/test/webdriver/AlertsTests.cs | 2 +-
4 files changed, 203 insertions(+), 216 deletions(-)
delete mode 100644 dotnet/src/webdriver/UnhandledPromptBehaviorOption.cs
create mode 100644 dotnet/src/webdriver/UserPromptHandler.cs
diff --git a/dotnet/src/webdriver/DriverOptions.cs b/dotnet/src/webdriver/DriverOptions.cs
index c20477873036b..39eb3b7925f1e 100644
--- a/dotnet/src/webdriver/DriverOptions.cs
+++ b/dotnet/src/webdriver/DriverOptions.cs
@@ -124,7 +124,7 @@ protected DriverOptions()
/// Gets or sets the value for describing how unexpected alerts are to be handled in the browser.
/// Defaults to .
///
- public UnhandledPromptBehaviorOption? UnhandledPromptBehavior { get; set; } = Selenium.UnhandledPromptBehavior.Default;
+ public UserPromptHandler? UnhandledPromptBehavior { get; set; } = Selenium.UnhandledPromptBehavior.Default;
///
/// Gets or sets the value for describing how the browser is to wait for pages to load in the browser.
diff --git a/dotnet/src/webdriver/UnhandledPromptBehaviorOption.cs b/dotnet/src/webdriver/UnhandledPromptBehaviorOption.cs
deleted file mode 100644
index 29e0768fab934..0000000000000
--- a/dotnet/src/webdriver/UnhandledPromptBehaviorOption.cs
+++ /dev/null
@@ -1,214 +0,0 @@
-//
-// 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;
-using System.Collections.Generic;
-
-namespace OpenQA.Selenium;
-
-///
-/// Represents a configuration option that determines how unhandled prompts are managed during automated browser
-/// interactions.
-///
-///
-/// Use this type to specify whether a single unhandled prompt behavior or multiple behaviors should be applied.
-/// The static methods provide convenient ways to create either a single-behavior or multi-behavior option.
-/// This abstraction is typically used in scenarios where browser automation frameworks need to control the handling of
-/// unexpected dialogs or prompts.
-///
-/// Available options:
-///
-/// - - Wraps a single value applied to all prompt types. Create via the implicit conversion from or by calling .
-/// - - Allows configuring per-prompt behaviors (Alert, Confirm, Prompt, BeforeUnload, Default). Create via .
-///
-///
-///
-public abstract record UnhandledPromptBehaviorOption
-{
- ///
- /// Converts a value of type to an instance.
- ///
- /// The value to convert.
- public static implicit operator UnhandledPromptBehaviorOption(UnhandledPromptBehavior value)
- => Single(value);
-
- ///
- /// Creates an representing a single value.
- ///
- /// The to apply for all prompt types.
- /// An wrapping the provided behavior.
- public static UnhandledPromptBehaviorSingleOption Single(UnhandledPromptBehavior value)
- => new(value);
-
- ///
- /// Creates an allowing individual values per prompt type.
- ///
- /// An with per-prompt configurable behaviors.
- public static UnhandledPromptBehaviorMultiOption Multi()
- => new();
-
- internal abstract object? ToCapabilities();
-
- internal static string ConvertBehaviorToString(UnhandledPromptBehavior behavior) =>
- behavior switch
- {
- UnhandledPromptBehavior.Ignore => "ignore",
- UnhandledPromptBehavior.Accept => "accept",
- UnhandledPromptBehavior.Dismiss => "dismiss",
- UnhandledPromptBehavior.AcceptAndNotify => "accept and notify",
- UnhandledPromptBehavior.DismissAndNotify => "dismiss and notify",
- _ => throw new ArgumentOutOfRangeException(nameof(behavior), $"UnhandledPromptBehavior value '{behavior}' is not recognized."),
- };
-}
-
-///
-/// Represents an option that specifies a single unhandled prompt behavior to use when interacting with browser dialogs.
-///
-/// The unhandled prompt behavior to apply. Specifies how unexpected browser prompts are handled during automation.
-public sealed record UnhandledPromptBehaviorSingleOption(UnhandledPromptBehavior Value) : UnhandledPromptBehaviorOption
-{
- internal override object? ToCapabilities()
- {
- if (Value == UnhandledPromptBehavior.Default)
- {
- return null;
- }
-
- return ConvertBehaviorToString(Value);
- }
-}
-
-///
-/// Represents a set of options that specify how unhandled browser prompts are handled for different prompt types.
-///
-/// Use this class to configure distinct behaviors for alert, confirm, prompt, and beforeunload dialogs
-/// encountered during browser automation. Each property allows you to control the response to a specific type of
-/// unhandled prompt, enabling fine-grained handling beyond a single global setting.
-public sealed record UnhandledPromptBehaviorMultiOption : UnhandledPromptBehaviorOption
-{
- ///
- /// Gets or sets the behavior to use when an unexpected alert is encountered during automation.
- ///
- public UnhandledPromptBehavior Alert { get; set; } = UnhandledPromptBehavior.Default;
-
- ///
- /// Gets or sets the behavior to use when a confirmation prompt is encountered.
- ///
- /// Set this property to specify how the system should respond to confirmation dialogs, such as
- /// JavaScript confirm boxes, during automated operations. The default value is , which applies the standard handling defined by the
- /// environment.
- public UnhandledPromptBehavior Confirm { get; set; } = UnhandledPromptBehavior.Default;
-
- ///
- /// Gets or sets the behavior to use when an unexpected prompt is encountered during automation.
- ///
- /// Set this property to control how the system responds to unhandled prompts, such as alerts or
- /// confirmation dialogs, that appear unexpectedly. The default behavior is determined by the value of
- /// .
- public UnhandledPromptBehavior Prompt { get; set; } = UnhandledPromptBehavior.Default;
-
- ///
- /// Gets or sets the behavior to use when an unexpected beforeunload dialog is encountered.
- ///
- /// Use this property to specify how the application should respond to beforeunload dialogs that
- /// appear unexpectedly during automated browser interactions. This setting determines whether such dialogs are
- /// automatically accepted, dismissed, or cause an error.
- public UnhandledPromptBehavior BeforeUnload { get; set; } = UnhandledPromptBehavior.Default;
-
- ///
- /// Gets or sets the default behavior to use when an unexpected browser prompt is encountered.
- ///
- public UnhandledPromptBehavior Default { get; set; } = UnhandledPromptBehavior.Default;
-
- internal override object? ToCapabilities()
- {
- if (this == new UnhandledPromptBehaviorMultiOption())
- {
- return null;
- }
-
- Dictionary capabilities = [];
-
- if (Alert != default)
- {
- capabilities["alert"] = ConvertBehaviorToString(Alert);
- }
-
- if (Confirm != default)
- {
- capabilities["confirm"] = ConvertBehaviorToString(Confirm);
- }
-
- if (Prompt != default)
- {
- capabilities["prompt"] = ConvertBehaviorToString(Prompt);
- }
-
- if (BeforeUnload != default)
- {
- capabilities["beforeUnload"] = ConvertBehaviorToString(BeforeUnload);
- }
-
- if (Default != default)
- {
- capabilities["default"] = ConvertBehaviorToString(Default);
- }
-
- return capabilities;
- }
-}
-
-///
-/// Specifies the behavior of handling unexpected alerts in the IE driver.
-///
-public enum UnhandledPromptBehavior
-{
- ///
- /// Indicates the behavior is not set.
- ///
- Default,
-
- ///
- /// Ignore unexpected alerts, such that the user must handle them.
- ///
- Ignore,
-
- ///
- /// Accept unexpected alerts.
- ///
- Accept,
-
- ///
- /// Dismiss unexpected alerts.
- ///
- Dismiss,
-
- ///
- /// Accepts unexpected alerts and notifies the user that the alert has
- /// been accepted by throwing an
- ///
- AcceptAndNotify,
-
- ///
- /// Dismisses unexpected alerts and notifies the user that the alert has
- /// been dismissed by throwing an
- ///
- DismissAndNotify
-}
diff --git a/dotnet/src/webdriver/UserPromptHandler.cs b/dotnet/src/webdriver/UserPromptHandler.cs
new file mode 100644
index 0000000000000..7a981220b43a3
--- /dev/null
+++ b/dotnet/src/webdriver/UserPromptHandler.cs
@@ -0,0 +1,201 @@
+//
+// 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;
+using System.Collections.Generic;
+
+namespace OpenQA.Selenium;
+
+///
+/// Represents a WebDriver session's user prompt handler, which defines how unhandled browser prompts
+/// (alerts, confirms, prompts, beforeunload dialogs) are managed during automation.
+///
+///
+/// This corresponds to the W3C WebDriver unhandledPromptBehavior capability, which may be expressed
+/// either as a single string applied to all prompt types, or as a per-prompt-type map.
+///
+/// Available variants:
+///
+/// - - Wraps a single value applied to all prompt types. Create via the implicit conversion from or by constructing directly.
+/// - - Allows configuring per-prompt behaviors (Alert, Confirm, Prompt, BeforeUnload, Default).
+///
+///
+///
+public abstract record UserPromptHandler
+{
+ private UserPromptHandler() { }
+
+ ///
+ /// Converts a value of type to a instance.
+ ///
+ /// The value to convert.
+ public static implicit operator UserPromptHandler(UnhandledPromptBehavior value)
+ => new Uniform(value);
+
+ internal abstract object? ToCapabilities();
+
+ private static string ConvertBehaviorToString(UnhandledPromptBehavior behavior) =>
+ behavior switch
+ {
+ UnhandledPromptBehavior.Ignore => "ignore",
+ UnhandledPromptBehavior.Accept => "accept",
+ UnhandledPromptBehavior.Dismiss => "dismiss",
+ UnhandledPromptBehavior.AcceptAndNotify => "accept and notify",
+ UnhandledPromptBehavior.DismissAndNotify => "dismiss and notify",
+ _ => throw new InvalidOperationException($"UnhandledPromptBehavior value '{behavior}' is not recognized."),
+ };
+
+ ///
+ /// Represents a user prompt handler that applies a single value
+ /// as the fallback default for all prompt types.
+ ///
+ /// The unhandled prompt behavior to apply. Specifies how unexpected browser prompts are handled during automation.
+ public sealed record Uniform(UnhandledPromptBehavior Value) : UserPromptHandler
+ {
+ internal override object? ToCapabilities()
+ {
+ if (Value == UnhandledPromptBehavior.Default)
+ {
+ return null;
+ }
+
+ return ConvertBehaviorToString(Value);
+ }
+ }
+
+ ///
+ /// Represents a user prompt handler that specifies distinct values
+ /// for individual prompt types (alert, confirm, prompt, beforeunload), with a fallback default.
+ ///
+ /// Use this variant to configure distinct behaviors for alert, confirm, prompt, and beforeunload dialogs
+ /// encountered during browser automation. Each property allows you to control the response to a specific type of
+ /// unhandled prompt, enabling fine-grained handling beyond a single global setting.
+ public sealed record PerPromptType : UserPromptHandler
+ {
+ ///
+ /// Gets or sets the behavior to use when an unexpected alert is encountered during automation.
+ ///
+ public UnhandledPromptBehavior Alert { get; set; } = UnhandledPromptBehavior.Default;
+
+ ///
+ /// Gets or sets the behavior to use when a confirmation prompt is encountered.
+ ///
+ /// Set this property to specify how the system should respond to confirmation dialogs, such as
+ /// JavaScript confirm boxes, during automated operations. The default value is , which applies the standard handling defined by the
+ /// environment.
+ public UnhandledPromptBehavior Confirm { get; set; } = UnhandledPromptBehavior.Default;
+
+ ///
+ /// Gets or sets the behavior to use when an unexpected prompt is encountered during automation.
+ ///
+ /// Set this property to control how the system responds to unhandled prompts, such as alerts or
+ /// confirmation dialogs, that appear unexpectedly. The default behavior is determined by the value of
+ /// .
+ public UnhandledPromptBehavior Prompt { get; set; } = UnhandledPromptBehavior.Default;
+
+ ///
+ /// Gets or sets the behavior to use when an unexpected beforeunload dialog is encountered.
+ ///
+ /// Use this property to specify how the application should respond to beforeunload dialogs that
+ /// appear unexpectedly during automated browser interactions. This setting determines whether such dialogs are
+ /// automatically accepted, dismissed, or cause an error.
+ public UnhandledPromptBehavior BeforeUnload { get; set; } = UnhandledPromptBehavior.Default;
+
+ ///
+ /// Gets or sets the default behavior to use when an unexpected browser prompt is encountered.
+ ///
+ public UnhandledPromptBehavior Default { get; set; } = UnhandledPromptBehavior.Default;
+
+ internal override object? ToCapabilities()
+ {
+ if (this == new PerPromptType())
+ {
+ return null;
+ }
+
+ Dictionary capabilities = [];
+
+ if (Alert != default)
+ {
+ capabilities["alert"] = ConvertBehaviorToString(Alert);
+ }
+
+ if (Confirm != default)
+ {
+ capabilities["confirm"] = ConvertBehaviorToString(Confirm);
+ }
+
+ if (Prompt != default)
+ {
+ capabilities["prompt"] = ConvertBehaviorToString(Prompt);
+ }
+
+ if (BeforeUnload != default)
+ {
+ capabilities["beforeUnload"] = ConvertBehaviorToString(BeforeUnload);
+ }
+
+ if (Default != default)
+ {
+ capabilities["default"] = ConvertBehaviorToString(Default);
+ }
+
+ return capabilities;
+ }
+ }
+}
+
+///
+/// Specifies the behavior of handling unexpected alerts in the IE driver.
+///
+public enum UnhandledPromptBehavior
+{
+ ///
+ /// Indicates the behavior is not set.
+ ///
+ Default,
+
+ ///
+ /// Ignore unexpected alerts, such that the user must handle them.
+ ///
+ Ignore,
+
+ ///
+ /// Accept unexpected alerts.
+ ///
+ Accept,
+
+ ///
+ /// Dismiss unexpected alerts.
+ ///
+ Dismiss,
+
+ ///
+ /// Accepts unexpected alerts and notifies the user that the alert has
+ /// been accepted by throwing an
+ ///
+ AcceptAndNotify,
+
+ ///
+ /// Dismisses unexpected alerts and notifies the user that the alert has
+ /// been dismissed by throwing an
+ ///
+ DismissAndNotify
+}
diff --git a/dotnet/test/webdriver/AlertsTests.cs b/dotnet/test/webdriver/AlertsTests.cs
index 3d756b126b666..03adf54bb1237 100644
--- a/dotnet/test/webdriver/AlertsTests.cs
+++ b/dotnet/test/webdriver/AlertsTests.cs
@@ -39,7 +39,7 @@ public void ShouldBeAbleToDismissTheWindowAlert()
{
using var driver = EnvironmentManager.Instance.CreateDriverInstance(new CustomAlertDriverOptions
{
- UnhandledPromptBehavior = new UnhandledPromptBehaviorMultiOption { Default = UnhandledPromptBehavior.Dismiss }
+ UnhandledPromptBehavior = new UserPromptHandler.PerPromptType { Default = UnhandledPromptBehavior.Dismiss }
});
driver.Url = CreateAlertPage("cheese");
From 3225204d9deef2d419df1b272fcf73865668532b Mon Sep 17 00:00:00 2001
From: Nikolay Borisenko <22616990+nvborisenko@users.noreply.github.com>
Date: Thu, 23 Apr 2026 21:02:26 +0300
Subject: [PATCH 18/26] Support File handler
---
dotnet/src/webdriver/UserPromptHandler.cs | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/dotnet/src/webdriver/UserPromptHandler.cs b/dotnet/src/webdriver/UserPromptHandler.cs
index 7a981220b43a3..21ad794617638 100644
--- a/dotnet/src/webdriver/UserPromptHandler.cs
+++ b/dotnet/src/webdriver/UserPromptHandler.cs
@@ -118,6 +118,12 @@ public sealed record PerPromptType : UserPromptHandler
/// automatically accepted, dismissed, or cause an error.
public UnhandledPromptBehavior BeforeUnload { get; set; } = UnhandledPromptBehavior.Default;
+ ///
+ /// Gets or sets the behavior to use when an unexpected file selection dialog is encountered.
+ ///
+ /// The "file" prompt type is respected only in WebDriver BiDi sessions.
+ public UnhandledPromptBehavior File { get; set; } = UnhandledPromptBehavior.Default;
+
///
/// Gets or sets the default behavior to use when an unexpected browser prompt is encountered.
///
@@ -152,6 +158,11 @@ public sealed record PerPromptType : UserPromptHandler
capabilities["beforeUnload"] = ConvertBehaviorToString(BeforeUnload);
}
+ if (File != default)
+ {
+ capabilities["file"] = ConvertBehaviorToString(File);
+ }
+
if (Default != default)
{
capabilities["default"] = ConvertBehaviorToString(Default);
From b984c9fd13bf854525cae3a2034f12a5d2947500 Mon Sep 17 00:00:00 2001
From: Nikolay Borisenko <22616990+nvborisenko@users.noreply.github.com>
Date: Thu, 23 Apr 2026 21:02:55 +0300
Subject: [PATCH 19/26] Clean
---
dotnet/src/webdriver/UserPromptHandler.cs | 3 ---
1 file changed, 3 deletions(-)
diff --git a/dotnet/src/webdriver/UserPromptHandler.cs b/dotnet/src/webdriver/UserPromptHandler.cs
index 21ad794617638..f914367fd24c4 100644
--- a/dotnet/src/webdriver/UserPromptHandler.cs
+++ b/dotnet/src/webdriver/UserPromptHandler.cs
@@ -17,9 +17,6 @@
// under the License.
//
-using System;
-using System.Collections.Generic;
-
namespace OpenQA.Selenium;
///
From 832d645e8127494870f80b91ea67c82fe4034bdb Mon Sep 17 00:00:00 2001
From: Nikolay Borisenko <22616990+nvborisenko@users.noreply.github.com>
Date: Thu, 23 Apr 2026 21:28:59 +0300
Subject: [PATCH 20/26] Nullable instead of default, obsoleting Default
---
dotnet/src/webdriver/DriverOptions.cs | 4 +-
dotnet/src/webdriver/UserPromptHandler.cs | 101 ++++++++----------
.../webdriver/UnexpectedAlertBehaviorTests.cs | 11 +-
3 files changed, 49 insertions(+), 67 deletions(-)
diff --git a/dotnet/src/webdriver/DriverOptions.cs b/dotnet/src/webdriver/DriverOptions.cs
index 39eb3b7925f1e..2de9dd2cbb4c9 100644
--- a/dotnet/src/webdriver/DriverOptions.cs
+++ b/dotnet/src/webdriver/DriverOptions.cs
@@ -122,9 +122,9 @@ protected DriverOptions()
///
/// Gets or sets the value for describing how unexpected alerts are to be handled in the browser.
- /// Defaults to .
+ /// Defaults to , leaving the behavior unset.
///
- public UserPromptHandler? UnhandledPromptBehavior { get; set; } = Selenium.UnhandledPromptBehavior.Default;
+ public UserPromptHandler? UnhandledPromptBehavior { get; set; }
///
/// Gets or sets the value for describing how the browser is to wait for pages to load in the browser.
diff --git a/dotnet/src/webdriver/UserPromptHandler.cs b/dotnet/src/webdriver/UserPromptHandler.cs
index f914367fd24c4..b0bd801fb3ae2 100644
--- a/dotnet/src/webdriver/UserPromptHandler.cs
+++ b/dotnet/src/webdriver/UserPromptHandler.cs
@@ -39,11 +39,12 @@ public abstract record UserPromptHandler
private UserPromptHandler() { }
///
- /// Converts a value of type to a instance.
+ /// Converts a nullable to a instance,
+ /// or when is .
///
/// The value to convert.
- public static implicit operator UserPromptHandler(UnhandledPromptBehavior value)
- => new Uniform(value);
+ public static implicit operator UserPromptHandler?(UnhandledPromptBehavior? value)
+ => value is { } v ? new Uniform(v) : null;
internal abstract object? ToCapabilities();
@@ -55,6 +56,9 @@ private static string ConvertBehaviorToString(UnhandledPromptBehavior behavior)
UnhandledPromptBehavior.Dismiss => "dismiss",
UnhandledPromptBehavior.AcceptAndNotify => "accept and notify",
UnhandledPromptBehavior.DismissAndNotify => "dismiss and notify",
+#pragma warning disable CS0618 // UnhandledPromptBehavior.Default is obsolete
+ UnhandledPromptBehavior.Default => throw new InvalidOperationException("UnhandledPromptBehavior.Default has no wire representation; pass null instead."),
+#pragma warning restore CS0618
_ => throw new InvalidOperationException($"UnhandledPromptBehavior value '{behavior}' is not recognized."),
};
@@ -67,10 +71,12 @@ public sealed record Uniform(UnhandledPromptBehavior Value) : UserPromptHandler
{
internal override object? ToCapabilities()
{
+#pragma warning disable CS0618 // UnhandledPromptBehavior.Default is obsolete
if (Value == UnhandledPromptBehavior.Default)
{
return null;
}
+#pragma warning restore CS0618
return ConvertBehaviorToString(Value);
}
@@ -86,86 +92,62 @@ public sealed record Uniform(UnhandledPromptBehavior Value) : UserPromptHandler
public sealed record PerPromptType : UserPromptHandler
{
///
- /// Gets or sets the behavior to use when an unexpected alert is encountered during automation.
+ /// Gets or sets the behavior to use when an unexpected alert is encountered during automation,
+ /// or to leave it unset.
///
- public UnhandledPromptBehavior Alert { get; set; } = UnhandledPromptBehavior.Default;
+ public UnhandledPromptBehavior? Alert { get; set; }
///
- /// Gets or sets the behavior to use when a confirmation prompt is encountered.
+ /// Gets or sets the behavior to use when a confirmation prompt is encountered,
+ /// or to leave it unset.
///
- /// Set this property to specify how the system should respond to confirmation dialogs, such as
- /// JavaScript confirm boxes, during automated operations. The default value is , which applies the standard handling defined by the
- /// environment.
- public UnhandledPromptBehavior Confirm { get; set; } = UnhandledPromptBehavior.Default;
+ public UnhandledPromptBehavior? Confirm { get; set; }
///
- /// Gets or sets the behavior to use when an unexpected prompt is encountered during automation.
+ /// Gets or sets the behavior to use when an unexpected prompt is encountered during automation,
+ /// or to leave it unset.
///
- /// Set this property to control how the system responds to unhandled prompts, such as alerts or
- /// confirmation dialogs, that appear unexpectedly. The default behavior is determined by the value of
- /// .
- public UnhandledPromptBehavior Prompt { get; set; } = UnhandledPromptBehavior.Default;
+ public UnhandledPromptBehavior? Prompt { get; set; }
///
- /// Gets or sets the behavior to use when an unexpected beforeunload dialog is encountered.
+ /// Gets or sets the behavior to use when an unexpected beforeunload dialog is encountered,
+ /// or to leave it unset.
///
- /// Use this property to specify how the application should respond to beforeunload dialogs that
- /// appear unexpectedly during automated browser interactions. This setting determines whether such dialogs are
- /// automatically accepted, dismissed, or cause an error.
- public UnhandledPromptBehavior BeforeUnload { get; set; } = UnhandledPromptBehavior.Default;
+ public UnhandledPromptBehavior? BeforeUnload { get; set; }
///
- /// Gets or sets the behavior to use when an unexpected file selection dialog is encountered.
+ /// Gets or sets the behavior to use when an unexpected file selection dialog is encountered,
+ /// or to leave it unset.
///
/// The "file" prompt type is respected only in WebDriver BiDi sessions.
- public UnhandledPromptBehavior File { get; set; } = UnhandledPromptBehavior.Default;
+ public UnhandledPromptBehavior? File { get; set; }
///
- /// Gets or sets the default behavior to use when an unexpected browser prompt is encountered.
+ /// Gets or sets the fallback behavior to use when no specific handler is defined for a given prompt type,
+ /// or to leave it unset.
///
- public UnhandledPromptBehavior Default { get; set; } = UnhandledPromptBehavior.Default;
+ public UnhandledPromptBehavior? Default { get; set; }
internal override object? ToCapabilities()
{
- if (this == new PerPromptType())
- {
- return null;
- }
-
Dictionary capabilities = [];
+ AddIfSet(capabilities, "alert", Alert);
+ AddIfSet(capabilities, "confirm", Confirm);
+ AddIfSet(capabilities, "prompt", Prompt);
+ AddIfSet(capabilities, "beforeUnload", BeforeUnload);
+ AddIfSet(capabilities, "file", File);
+ AddIfSet(capabilities, "default", Default);
+ return capabilities.Count == 0 ? null : capabilities;
+ }
- if (Alert != default)
- {
- capabilities["alert"] = ConvertBehaviorToString(Alert);
- }
-
- if (Confirm != default)
- {
- capabilities["confirm"] = ConvertBehaviorToString(Confirm);
- }
-
- if (Prompt != default)
- {
- capabilities["prompt"] = ConvertBehaviorToString(Prompt);
- }
-
- if (BeforeUnload != default)
- {
- capabilities["beforeUnload"] = ConvertBehaviorToString(BeforeUnload);
- }
-
- if (File != default)
- {
- capabilities["file"] = ConvertBehaviorToString(File);
- }
-
- if (Default != default)
+ private static void AddIfSet(Dictionary capabilities, string key, UnhandledPromptBehavior? value)
+ {
+#pragma warning disable CS0618 // UnhandledPromptBehavior.Default is obsolete
+ if (value is { } v && v != UnhandledPromptBehavior.Default)
+#pragma warning restore CS0618
{
- capabilities["default"] = ConvertBehaviorToString(Default);
+ capabilities[key] = ConvertBehaviorToString(v);
}
-
- return capabilities;
}
}
}
@@ -178,6 +160,7 @@ public enum UnhandledPromptBehavior
///
/// Indicates the behavior is not set.
///
+ [Obsolete("Use a nullable UnhandledPromptBehavior? and pass null to leave the behavior unset. This member will be removed in v4.46.")]
Default,
///
diff --git a/dotnet/test/webdriver/UnexpectedAlertBehaviorTests.cs b/dotnet/test/webdriver/UnexpectedAlertBehaviorTests.cs
index f93e1f54a113a..b572f8ab254d3 100644
--- a/dotnet/test/webdriver/UnexpectedAlertBehaviorTests.cs
+++ b/dotnet/test/webdriver/UnexpectedAlertBehaviorTests.cs
@@ -71,7 +71,7 @@ public void CanSilentlyDismissUnhandledAlert()
[Test]
public void CanDismissUnhandledAlertsByDefault()
{
- ExecuteTestWithUnhandledPrompt(UnhandledPromptBehavior.Default, "null");
+ ExecuteTestWithUnhandledPrompt(null, "null");
}
[Test]
@@ -82,14 +82,13 @@ public void CanIgnoreUnhandledAlert()
localDriver.SwitchTo().Alert().Dismiss();
}
- private void ExecuteTestWithUnhandledPrompt(UnhandledPromptBehavior behavior, string expectedAlertText)
+ private void ExecuteTestWithUnhandledPrompt(UnhandledPromptBehavior? behavior, string expectedAlertText)
{
bool silentlyHandlePrompt = behavior == UnhandledPromptBehavior.Accept || behavior == UnhandledPromptBehavior.Dismiss;
- UnhandledPromptBehaviorOptions options = new UnhandledPromptBehaviorOptions();
- if (behavior != UnhandledPromptBehavior.Default)
+ UnhandledPromptBehaviorOptions options = new()
{
- options.UnhandledPromptBehavior = behavior;
- }
+ UnhandledPromptBehavior = behavior,
+ };
localDriver = EnvironmentManager.Instance.CreateDriverInstance(options);
localDriver.Url = alertsPage;
From 8186fb76f42fb237efb800a67c264477d95455a8 Mon Sep 17 00:00:00 2001
From: Nikolay Borisenko <22616990+nvborisenko@users.noreply.github.com>
Date: Thu, 23 Apr 2026 21:37:17 +0300
Subject: [PATCH 21/26] Init
---
dotnet/src/webdriver/UserPromptHandler.cs | 31 ++++++++++-------------
1 file changed, 14 insertions(+), 17 deletions(-)
diff --git a/dotnet/src/webdriver/UserPromptHandler.cs b/dotnet/src/webdriver/UserPromptHandler.cs
index b0bd801fb3ae2..37383bc638852 100644
--- a/dotnet/src/webdriver/UserPromptHandler.cs
+++ b/dotnet/src/webdriver/UserPromptHandler.cs
@@ -56,9 +56,6 @@ private static string ConvertBehaviorToString(UnhandledPromptBehavior behavior)
UnhandledPromptBehavior.Dismiss => "dismiss",
UnhandledPromptBehavior.AcceptAndNotify => "accept and notify",
UnhandledPromptBehavior.DismissAndNotify => "dismiss and notify",
-#pragma warning disable CS0618 // UnhandledPromptBehavior.Default is obsolete
- UnhandledPromptBehavior.Default => throw new InvalidOperationException("UnhandledPromptBehavior.Default has no wire representation; pass null instead."),
-#pragma warning restore CS0618
_ => throw new InvalidOperationException($"UnhandledPromptBehavior value '{behavior}' is not recognized."),
};
@@ -92,41 +89,41 @@ public sealed record Uniform(UnhandledPromptBehavior Value) : UserPromptHandler
public sealed record PerPromptType : UserPromptHandler
{
///
- /// Gets or sets the behavior to use when an unexpected alert is encountered during automation,
+ /// Gets the behavior to use when an unexpected alert is encountered during automation,
/// or to leave it unset.
///
- public UnhandledPromptBehavior? Alert { get; set; }
+ public UnhandledPromptBehavior? Alert { get; init; }
///
- /// Gets or sets the behavior to use when a confirmation prompt is encountered,
+ /// Gets the behavior to use when a confirmation prompt is encountered,
/// or to leave it unset.
///
- public UnhandledPromptBehavior? Confirm { get; set; }
+ public UnhandledPromptBehavior? Confirm { get; init; }
///
- /// Gets or sets the behavior to use when an unexpected prompt is encountered during automation,
+ /// Gets the behavior to use when an unexpected prompt is encountered during automation,
/// or to leave it unset.
///
- public UnhandledPromptBehavior? Prompt { get; set; }
+ public UnhandledPromptBehavior? Prompt { get; init; }
///
- /// Gets or sets the behavior to use when an unexpected beforeunload dialog is encountered,
+ /// Gets the behavior to use when an unexpected beforeunload dialog is encountered,
/// or to leave it unset.
///
- public UnhandledPromptBehavior? BeforeUnload { get; set; }
+ public UnhandledPromptBehavior? BeforeUnload { get; init; }
///
- /// Gets or sets the behavior to use when an unexpected file selection dialog is encountered,
+ /// Gets the behavior to use when an unexpected file selection dialog is encountered,
/// or to leave it unset.
///
/// The "file" prompt type is respected only in WebDriver BiDi sessions.
- public UnhandledPromptBehavior? File { get; set; }
+ public UnhandledPromptBehavior? File { get; init; }
///
- /// Gets or sets the fallback behavior to use when no specific handler is defined for a given prompt type,
+ /// Gets the fallback behavior to use when no specific handler is defined for a given prompt type,
/// or to leave it unset.
///
- public UnhandledPromptBehavior? Default { get; set; }
+ public UnhandledPromptBehavior? Default { get; init; }
internal override object? ToCapabilities()
{
@@ -144,10 +141,10 @@ private static void AddIfSet(Dictionary capabilities, string key
{
#pragma warning disable CS0618 // UnhandledPromptBehavior.Default is obsolete
if (value is { } v && v != UnhandledPromptBehavior.Default)
-#pragma warning restore CS0618
{
capabilities[key] = ConvertBehaviorToString(v);
}
+#pragma warning restore CS0618
}
}
}
@@ -158,7 +155,7 @@ private static void AddIfSet(Dictionary capabilities, string key
public enum UnhandledPromptBehavior
{
///
- /// Indicates the behavior is not set.
+ /// Sentinel value meaning "behavior not set". Not part of the W3C WebDriver spec.
///
[Obsolete("Use a nullable UnhandledPromptBehavior? and pass null to leave the behavior unset. This member will be removed in v4.46.")]
Default,
From 9894ffcf0d984ff3c31191f43b71a8c6d9a18a4d Mon Sep 17 00:00:00 2001
From: Nikolay Borisenko <22616990+nvborisenko@users.noreply.github.com>
Date: Thu, 23 Apr 2026 21:51:28 +0300
Subject: [PATCH 22/26] Docs UnhandledPromptBehavior
---
dotnet/src/webdriver/UserPromptHandler.cs | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/dotnet/src/webdriver/UserPromptHandler.cs b/dotnet/src/webdriver/UserPromptHandler.cs
index 37383bc638852..3bb5db141d4be 100644
--- a/dotnet/src/webdriver/UserPromptHandler.cs
+++ b/dotnet/src/webdriver/UserPromptHandler.cs
@@ -150,8 +150,14 @@ private static void AddIfSet(Dictionary capabilities, string key
}
///
-/// Specifies the behavior of handling unexpected alerts in the IE driver.
+/// Specifies how a WebDriver session handles an unhandled user prompt.
///
+///
+/// Corresponds to the handler values defined for the W3C WebDriver
+/// unhandledPromptBehavior capability:
+/// dismiss, accept, dismiss and notify, accept and notify, and ignore.
+/// When no handler is configured, the spec's implicit default is .
+///
public enum UnhandledPromptBehavior
{
///
From 0f1836f294d74d22442181cc36b49a20b7fd3b22 Mon Sep 17 00:00:00 2001
From: Nikolay Borisenko <22616990+nvborisenko@users.noreply.github.com>
Date: Thu, 23 Apr 2026 21:53:06 +0300
Subject: [PATCH 23/26] Update UserPromptHandler.cs
---
dotnet/src/webdriver/UserPromptHandler.cs | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/dotnet/src/webdriver/UserPromptHandler.cs b/dotnet/src/webdriver/UserPromptHandler.cs
index 3bb5db141d4be..4fadc2bb9fa38 100644
--- a/dotnet/src/webdriver/UserPromptHandler.cs
+++ b/dotnet/src/webdriver/UserPromptHandler.cs
@@ -21,7 +21,7 @@ namespace OpenQA.Selenium;
///
/// Represents a WebDriver session's user prompt handler, which defines how unhandled browser prompts
-/// (alerts, confirms, prompts, beforeunload dialogs) are managed during automation.
+/// (alerts, confirms, prompts, beforeunload dialogs, file selection dialogs) are managed during automation.
///
///
/// This corresponds to the W3C WebDriver unhandledPromptBehavior capability, which may be expressed
@@ -30,7 +30,7 @@ namespace OpenQA.Selenium;
/// Available variants:
///
/// - - Wraps a single value applied to all prompt types. Create via the implicit conversion from or by constructing directly.
-/// - - Allows configuring per-prompt behaviors (Alert, Confirm, Prompt, BeforeUnload, Default).
+/// - - Allows configuring per-prompt behaviors (Alert, Confirm, Prompt, BeforeUnload, File, Default).
///
///
///
@@ -81,11 +81,11 @@ public sealed record Uniform(UnhandledPromptBehavior Value) : UserPromptHandler
///
/// Represents a user prompt handler that specifies distinct values
- /// for individual prompt types (alert, confirm, prompt, beforeunload), with a fallback default.
+ /// for individual prompt types (alert, confirm, prompt, beforeunload, file), with a fallback default.
///
- /// Use this variant to configure distinct behaviors for alert, confirm, prompt, and beforeunload dialogs
- /// encountered during browser automation. Each property allows you to control the response to a specific type of
- /// unhandled prompt, enabling fine-grained handling beyond a single global setting.
+ /// Use this variant to configure distinct behaviors for alert, confirm, prompt, beforeunload, and file
+ /// selection dialogs encountered during browser automation. Each property allows you to control the response to a
+ /// specific type of unhandled prompt, enabling fine-grained handling beyond a single global setting.
public sealed record PerPromptType : UserPromptHandler
{
///
From f15b022e54c8b03e282213b7111bfe1f0efea00f Mon Sep 17 00:00:00 2001
From: Nikolay Borisenko <22616990+nvborisenko@users.noreply.github.com>
Date: Fri, 24 Apr 2026 10:38:54 +0300
Subject: [PATCH 24/26] Thows.Nothing in assertion
---
dotnet/test/webdriver/AlertsTests.cs | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/dotnet/test/webdriver/AlertsTests.cs b/dotnet/test/webdriver/AlertsTests.cs
index 03adf54bb1237..681d976a07e11 100644
--- a/dotnet/test/webdriver/AlertsTests.cs
+++ b/dotnet/test/webdriver/AlertsTests.cs
@@ -46,8 +46,9 @@ public void ShouldBeAbleToDismissTheWindowAlert()
driver.FindElement(By.Id("alert")).Click();
- // If we can perform any action again, we're good to go
- driver.FindElement(By.Id("alert")).Click();
+ Assert.That(
+ () => driver.FindElement(By.Id("alert")).Click(),
+ Throws.Nothing, "Unexpected alert was not dismissed as expected");
}
[Test]
From b46633ccdb9d09c8f7beb16fc016950786608c40 Mon Sep 17 00:00:00 2001
From: Nikolay Borisenko <22616990+nvborisenko@users.noreply.github.com>
Date: Fri, 24 Apr 2026 11:42:55 +0300
Subject: [PATCH 25/26] Move test to proper fixture
---
dotnet/test/webdriver/AlertsTests.cs | 30 ------------
.../webdriver/UnexpectedAlertBehaviorTests.cs | 46 ++++++++-----------
2 files changed, 20 insertions(+), 56 deletions(-)
diff --git a/dotnet/test/webdriver/AlertsTests.cs b/dotnet/test/webdriver/AlertsTests.cs
index 681d976a07e11..49486304d0c5d 100644
--- a/dotnet/test/webdriver/AlertsTests.cs
+++ b/dotnet/test/webdriver/AlertsTests.cs
@@ -34,23 +34,6 @@ public void ShouldBeAbleToOverrideTheWindowAlertMethod()
driver.FindElement(By.Id("alert")).Click();
}
- [Test]
- public void ShouldBeAbleToDismissTheWindowAlert()
- {
- using var driver = EnvironmentManager.Instance.CreateDriverInstance(new CustomAlertDriverOptions
- {
- UnhandledPromptBehavior = new UserPromptHandler.PerPromptType { Default = UnhandledPromptBehavior.Dismiss }
- });
-
- driver.Url = CreateAlertPage("cheese");
-
- driver.FindElement(By.Id("alert")).Click();
-
- Assert.That(
- () => driver.FindElement(By.Id("alert")).Click(),
- Throws.Nothing, "Unexpected alert was not dismissed as expected");
- }
-
[Test]
public void ShouldAllowUsersToAcceptAnAlertManually()
{
@@ -572,17 +555,4 @@ private Func WindowHandleCountToBe(int count)
return driver.WindowHandles.Count == count;
};
}
-
- class CustomAlertDriverOptions : DriverOptions
- {
- public CustomAlertDriverOptions()
- {
-
- }
-
- public override ICapabilities ToCapabilities()
- {
- return null;
- }
- }
}
diff --git a/dotnet/test/webdriver/UnexpectedAlertBehaviorTests.cs b/dotnet/test/webdriver/UnexpectedAlertBehaviorTests.cs
index b572f8ab254d3..45e875c1a4129 100644
--- a/dotnet/test/webdriver/UnexpectedAlertBehaviorTests.cs
+++ b/dotnet/test/webdriver/UnexpectedAlertBehaviorTests.cs
@@ -74,17 +74,33 @@ public void CanDismissUnhandledAlertsByDefault()
ExecuteTestWithUnhandledPrompt(null, "null");
}
+ [Test]
+ public void CanDismissUnhandledAlertsViaPerType()
+ {
+ ExecuteTestWithUnhandledPrompt(new UserPromptHandler.PerPromptType
+ {
+ Alert = UnhandledPromptBehavior.Dismiss
+ }, "null");
+ }
+
+ [Test]
+ public void CanDismissUnhandledAlertsViaDefaultPerType()
+ {
+ ExecuteTestWithUnhandledPrompt(new UserPromptHandler.PerPromptType(), "null");
+ }
+
[Test]
[IgnoreBrowser(Browser.Safari, "Test hangs waiting for alert acknowledgement in Safari, but works in Tech Preview")]
public void CanIgnoreUnhandledAlert()
{
- Assert.That(() => ExecuteTestWithUnhandledPrompt(UnhandledPromptBehavior.Ignore, "Text ignored"), Throws.InstanceOf().With.InnerException.InstanceOf());
+ Assert.That(
+ () => ExecuteTestWithUnhandledPrompt(UnhandledPromptBehavior.Ignore, "Text ignored"),
+ Throws.InstanceOf().With.InnerException.InstanceOf());
localDriver.SwitchTo().Alert().Dismiss();
}
- private void ExecuteTestWithUnhandledPrompt(UnhandledPromptBehavior? behavior, string expectedAlertText)
+ private void ExecuteTestWithUnhandledPrompt(UserPromptHandler behavior, string expectedAlertText)
{
- bool silentlyHandlePrompt = behavior == UnhandledPromptBehavior.Accept || behavior == UnhandledPromptBehavior.Dismiss;
UnhandledPromptBehaviorOptions options = new()
{
UnhandledPromptBehavior = behavior,
@@ -95,31 +111,9 @@ private void ExecuteTestWithUnhandledPrompt(UnhandledPromptBehavior? behavior, s
IWebElement resultElement = localDriver.FindElement(By.Id("text"));
localDriver.FindElement(By.Id("prompt-with-default")).Click();
- WaitFor(ElementTextToBeEqual(resultElement, expectedAlertText, silentlyHandlePrompt), "Did not find text");
+ WaitFor(() => resultElement.Text == expectedAlertText, "Did not find text");
}
- private Func ElementTextToBeEqual(IWebElement resultElement, string expectedAlertText, bool silentlyHandlePrompt)
- {
- return () =>
- {
- try
- {
- return resultElement.Text == expectedAlertText;
- }
- catch (UnhandledAlertException)
- {
- if (!silentlyHandlePrompt)
- {
- throw;
- }
- }
- catch (NoSuchElementException)
- {
- }
-
- return false;
- };
- }
public class UnhandledPromptBehaviorOptions : DriverOptions
{
From aa0ccefcba449db64e911f2690a253e96941d736 Mon Sep 17 00:00:00 2001
From: Nikolay Borisenko <22616990+nvborisenko@users.noreply.github.com>
Date: Fri, 24 Apr 2026 11:50:16 +0300
Subject: [PATCH 26/26] Serialize empty
---
dotnet/src/webdriver/UserPromptHandler.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dotnet/src/webdriver/UserPromptHandler.cs b/dotnet/src/webdriver/UserPromptHandler.cs
index 4fadc2bb9fa38..e226c79aab1fa 100644
--- a/dotnet/src/webdriver/UserPromptHandler.cs
+++ b/dotnet/src/webdriver/UserPromptHandler.cs
@@ -134,7 +134,7 @@ public sealed record PerPromptType : UserPromptHandler
AddIfSet(capabilities, "beforeUnload", BeforeUnload);
AddIfSet(capabilities, "file", File);
AddIfSet(capabilities, "default", Default);
- return capabilities.Count == 0 ? null : capabilities;
+ return capabilities;
}
private static void AddIfSet(Dictionary capabilities, string key, UnhandledPromptBehavior? value)