diff --git a/dotnet/src/webdriver/Chromium/ChromiumDriver.cs b/dotnet/src/webdriver/Chromium/ChromiumDriver.cs
index 9cfdb5e5a5d66..d6fbebd953d84 100644
--- a/dotnet/src/webdriver/Chromium/ChromiumDriver.cs
+++ b/dotnet/src/webdriver/Chromium/ChromiumDriver.cs
@@ -299,6 +299,8 @@ public void SetPermission(string permissionName, string permissionValue)
/// Creates a session to communicate with a browser using the Chromium Developer Tools debugging protocol.
///
/// The active session to use to communicate with the Chromium Developer Tools debugging protocol.
+ [RequiresUnreferencedCode(DevToolsSession.CDP_AOTIncompatibilityMessage)]
+ [RequiresDynamicCode(DevToolsSession.CDP_AOTIncompatibilityMessage)]
public DevToolsSession GetDevToolsSession()
{
return GetDevToolsSession(new DevToolsOptions() { ProtocolVersion = DevToolsSession.AutoDetectDevToolsProtocolVersion });
@@ -308,6 +310,8 @@ public DevToolsSession GetDevToolsSession()
/// Creates a session to communicate with a browser using the Chromium Developer Tools debugging protocol.
///
/// The active session to use to communicate with the Chromium Developer Tools debugging protocol.
+ [RequiresUnreferencedCode(DevToolsSession.CDP_AOTIncompatibilityMessage)]
+ [RequiresDynamicCode(DevToolsSession.CDP_AOTIncompatibilityMessage)]
public DevToolsSession GetDevToolsSession(DevToolsOptions options)
{
if (this.devToolsSession == null)
@@ -349,6 +353,8 @@ public DevToolsSession GetDevToolsSession(DevToolsOptions options)
/// The version of the Chromium Developer Tools protocol to use. Defaults to autodetect the protocol version.
/// The active session to use to communicate with the Chromium Developer Tools debugging protocol.
[Obsolete("Use GetDevToolsSession(DevToolsOptions options)")]
+ [RequiresUnreferencedCode(DevToolsSession.CDP_AOTIncompatibilityMessage)]
+ [RequiresDynamicCode(DevToolsSession.CDP_AOTIncompatibilityMessage)]
public DevToolsSession GetDevToolsSession(int devToolsProtocolVersion)
{
return GetDevToolsSession(new DevToolsOptions() { ProtocolVersion = devToolsProtocolVersion });
diff --git a/dotnet/src/webdriver/DevTools/DevToolsSession.cs b/dotnet/src/webdriver/DevTools/DevToolsSession.cs
index bc332a8fcfb99..28d9b9def942f 100644
--- a/dotnet/src/webdriver/DevTools/DevToolsSession.cs
+++ b/dotnet/src/webdriver/DevTools/DevToolsSession.cs
@@ -20,6 +20,7 @@
using OpenQA.Selenium.Internal.Logging;
using System;
using System.Collections.Concurrent;
+using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Net.Http;
using System.Text.Json;
@@ -35,8 +36,12 @@ namespace OpenQA.Selenium.DevTools
/// Represents a WebSocket connection to a running DevTools instance that can be used to send
/// commands and receive events.
///
+ [RequiresUnreferencedCode(CDP_AOTIncompatibilityMessage)]
+ [RequiresDynamicCode(CDP_AOTIncompatibilityMessage)]
public class DevToolsSession : IDevToolsSession
{
+ internal const string CDP_AOTIncompatibilityMessage = "CDP is not compatible with trimming or AOT.";
+
///
/// A value indicating that the version of the DevTools protocol in use
/// by the browser should be automatically detected.
diff --git a/dotnet/src/webdriver/DevTools/IDevTools.cs b/dotnet/src/webdriver/DevTools/IDevTools.cs
index aefcb807316cd..4c256730e1ff8 100644
--- a/dotnet/src/webdriver/DevTools/IDevTools.cs
+++ b/dotnet/src/webdriver/DevTools/IDevTools.cs
@@ -18,6 +18,7 @@
//
using System;
+using System.Diagnostics.CodeAnalysis;
#nullable enable
@@ -37,6 +38,8 @@ public interface IDevTools
/// Creates a session to communicate with a browser using a Developer Tools debugging protocol.
///
/// The active session to use to communicate with the Developer Tools debugging protocol.
+ [RequiresUnreferencedCode(DevToolsSession.CDP_AOTIncompatibilityMessage)]
+ [RequiresDynamicCode(DevToolsSession.CDP_AOTIncompatibilityMessage)]
DevToolsSession GetDevToolsSession();
///
@@ -45,6 +48,8 @@ public interface IDevTools
/// The options for the DevToolsSession to use.
/// The active session to use to communicate with the Developer Tools debugging protocol.
/// If is .
+ [RequiresUnreferencedCode(DevToolsSession.CDP_AOTIncompatibilityMessage)]
+ [RequiresDynamicCode(DevToolsSession.CDP_AOTIncompatibilityMessage)]
DevToolsSession GetDevToolsSession(DevToolsOptions options);
///
@@ -53,11 +58,15 @@ public interface IDevTools
/// The specific version of the Developer Tools debugging protocol to use.
/// The active session to use to communicate with the Developer Tools debugging protocol.
[Obsolete("Use GetDevToolsSession(DevToolsOptions options)")]
+ [RequiresUnreferencedCode(DevToolsSession.CDP_AOTIncompatibilityMessage)]
+ [RequiresDynamicCode(DevToolsSession.CDP_AOTIncompatibilityMessage)]
DevToolsSession GetDevToolsSession(int protocolVersion);
///
/// Closes a DevTools session
///
+ [RequiresUnreferencedCode(DevToolsSession.CDP_AOTIncompatibilityMessage)]
+ [RequiresDynamicCode(DevToolsSession.CDP_AOTIncompatibilityMessage)]
void CloseDevToolsSession();
}
}
diff --git a/dotnet/src/webdriver/DevTools/IDevToolsSession.cs b/dotnet/src/webdriver/DevTools/IDevToolsSession.cs
index 5f32d87c68564..705ef72649e55 100644
--- a/dotnet/src/webdriver/DevTools/IDevToolsSession.cs
+++ b/dotnet/src/webdriver/DevTools/IDevToolsSession.cs
@@ -18,6 +18,7 @@
//
using System;
+using System.Diagnostics.CodeAnalysis;
using System.Text.Json;
using System.Text.Json.Nodes;
using System.Threading;
@@ -63,6 +64,8 @@ public interface IDevToolsSession : IDisposable
/// to throw an exception if a response is not received; otherwise, .
/// The command response object implementing the interface.
/// If is .
+ [RequiresUnreferencedCode(DevToolsSession.CDP_AOTIncompatibilityMessage)]
+ [RequiresDynamicCode(DevToolsSession.CDP_AOTIncompatibilityMessage)]
Task?> SendCommand(TCommand command, CancellationToken cancellationToken, int? millisecondsTimeout, bool throwExceptionIfResponseNotReceived)
where TCommand : ICommand;
@@ -77,6 +80,8 @@ public interface IDevToolsSession : IDisposable
/// to throw an exception if a response is not received; otherwise, .
/// The command response object implementing the interface.
/// If is .
+ [RequiresUnreferencedCode(DevToolsSession.CDP_AOTIncompatibilityMessage)]
+ [RequiresDynamicCode(DevToolsSession.CDP_AOTIncompatibilityMessage)]
Task SendCommand(TCommand command, CancellationToken cancellationToken, int? millisecondsTimeout, bool throwExceptionIfResponseNotReceived)
where TCommand : ICommand
where TCommandResponse : ICommandResponse;
@@ -91,6 +96,8 @@ public interface IDevToolsSession : IDisposable
/// to throw an exception if a response is not received; otherwise, .
/// The command response object implementing the interface.
/// If is .
+ [RequiresUnreferencedCode(DevToolsSession.CDP_AOTIncompatibilityMessage)]
+ [RequiresDynamicCode(DevToolsSession.CDP_AOTIncompatibilityMessage)]
Task SendCommand(string commandName, JsonNode @params, CancellationToken cancellationToken, int? millisecondsTimeout, bool throwExceptionIfResponseNotReceived);
}
}
diff --git a/dotnet/src/webdriver/DevTools/Json/JsonEnumMemberConverter.cs b/dotnet/src/webdriver/DevTools/Json/JsonEnumMemberConverter.cs
index 7816e21761bcd..5de59cd8cfb61 100644
--- a/dotnet/src/webdriver/DevTools/Json/JsonEnumMemberConverter.cs
+++ b/dotnet/src/webdriver/DevTools/Json/JsonEnumMemberConverter.cs
@@ -19,6 +19,7 @@
using System;
using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Runtime.Serialization;
using System.Text.Json;
@@ -28,7 +29,7 @@
namespace OpenQA.Selenium.DevTools.Json
{
- internal sealed class JsonEnumMemberConverter : JsonConverter
+ internal sealed class JsonEnumMemberConverter<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] TEnum> : JsonConverter
where TEnum : struct, Enum
{
private readonly Dictionary _enumToString = new Dictionary();
diff --git a/dotnet/src/webdriver/INetwork.cs b/dotnet/src/webdriver/INetwork.cs
index ef97172bc45a2..7daab7f725da8 100644
--- a/dotnet/src/webdriver/INetwork.cs
+++ b/dotnet/src/webdriver/INetwork.cs
@@ -18,6 +18,7 @@
//
using System;
+using System.Diagnostics.CodeAnalysis;
using System.Threading.Tasks;
#nullable enable
@@ -79,12 +80,16 @@ public interface INetwork
/// Asynchronously starts monitoring for network traffic.
///
/// A task that represents the asynchronous operation.
+ [RequiresUnreferencedCode("Network monitoring is currently implemented with CDP. When it is implemented with BiDi, AOT will be supported")]
+ [RequiresDynamicCode("Network monitoring is currently implemented with CDP. When it is implemented with BiDi, AOT will be supported.")]
Task StartMonitoring();
///
/// Asynchronously stops monitoring for network traffic.
///
/// A task that represents the asynchronous operation.
+ [RequiresUnreferencedCode("Network monitoring is currently implemented with CDP. When it is implemented with BiDi, AOT will be supported")]
+ [RequiresDynamicCode("Network monitoring is currently implemented with CDP. When it is implemented with BiDi, AOT will be supported.")]
Task StopMonitoring();
}
}
diff --git a/dotnet/src/webdriver/Internal/TrimmingAttributes.cs b/dotnet/src/webdriver/Internal/TrimmingAttributes.cs
new file mode 100644
index 0000000000000..ed2cca3111998
--- /dev/null
+++ b/dotnet/src/webdriver/Internal/TrimmingAttributes.cs
@@ -0,0 +1,439 @@
+//
+// 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.
+//
+
+#nullable enable
+
+// As per guidance in https://devblogs.microsoft.com/dotnet/creating-aot-compatible-libraries/#targetframeworks
+
+#if !NET8_0_OR_GREATER
+
+namespace System.Diagnostics.CodeAnalysis
+{
+ ///
+ /// Indicates that the specified method requires the ability to generate new code at runtime,
+ /// for example through .
+ ///
+ ///
+ /// This allows tools to understand which methods are unsafe to call when compiling ahead of time.
+ ///
+ [AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor | AttributeTargets.Class, Inherited = false)]
+ internal sealed class RequiresDynamicCodeAttribute : Attribute
+ {
+ ///
+ /// Initializes a new instance of the class
+ /// with the specified message.
+ ///
+ ///
+ /// A message that contains information about the usage of dynamic code.
+ ///
+ public RequiresDynamicCodeAttribute(string message)
+ {
+ Message = message;
+ }
+
+ ///
+ /// Gets a message that contains information about the usage of dynamic code.
+ ///
+ public string Message { get; }
+
+ ///
+ /// Gets or sets an optional URL that contains more information about the method,
+ /// why it requires dynamic code, and what options a consumer has to deal with it.
+ ///
+ public string? Url { get; set; }
+ }
+
+ ///
+ /// Indicates that the specified method requires dynamic access to code that is not referenced
+ /// statically, for example through .
+ ///
+ ///
+ /// This allows tools to understand which methods are unsafe to call when removing unreferenced
+ /// code from an application.
+ ///
+ [AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor | AttributeTargets.Class, Inherited = false)]
+ internal sealed class RequiresUnreferencedCodeAttribute : Attribute
+ {
+ ///
+ /// Initializes a new instance of the class
+ /// with the specified message.
+ ///
+ ///
+ /// A message that contains information about the usage of unreferenced code.
+ ///
+ public RequiresUnreferencedCodeAttribute(string message)
+ {
+ Message = message;
+ }
+
+ ///
+ /// Gets a message that contains information about the usage of unreferenced code.
+ ///
+ public string Message { get; }
+
+ ///
+ /// Gets or sets an optional URL that contains more information about the method,
+ /// why it requires unreferenced code, and what options a consumer has to deal with it.
+ ///
+ public string? Url { get; set; }
+ }
+
+ ///
+ /// Suppresses reporting of a specific rule violation, allowing multiple suppressions on a
+ /// single code artifact.
+ ///
+ ///
+ /// is different than
+ /// in that it doesn't have a
+ /// . So it is always preserved in the compiled assembly.
+ ///
+ [AttributeUsage(AttributeTargets.All, Inherited = false, AllowMultiple = true)]
+ internal sealed class UnconditionalSuppressMessageAttribute : Attribute
+ {
+ ///
+ /// Initializes a new instance of the
+ /// class, specifying the category of the tool and the identifier for an analysis rule.
+ ///
+ /// The category for the attribute.
+ /// The identifier of the analysis rule the attribute applies to.
+ public UnconditionalSuppressMessageAttribute(string category, string checkId)
+ {
+ Category = category;
+ CheckId = checkId;
+ }
+
+ ///
+ /// Gets the category identifying the classification of the attribute.
+ ///
+ ///
+ /// The property describes the tool or tool analysis category
+ /// for which a message suppression attribute applies.
+ ///
+ public string Category { get; }
+
+ ///
+ /// Gets the identifier of the analysis tool rule to be suppressed.
+ ///
+ ///
+ /// Concatenated together, the and
+ /// properties form a unique check identifier.
+ ///
+ public string CheckId { get; }
+
+ ///
+ /// Gets or sets the scope of the code that is relevant for the attribute.
+ ///
+ ///
+ /// The Scope property is an optional argument that specifies the metadata scope for which
+ /// the attribute is relevant.
+ ///
+ public string? Scope { get; set; }
+
+ ///
+ /// Gets or sets a fully qualified path that represents the target of the attribute.
+ ///
+ ///
+ /// The property is an optional argument identifying the analysis target
+ /// of the attribute. An example value is "System.IO.Stream.ctor():System.Void".
+ /// Because it is fully qualified, it can be long, particularly for targets such as parameters.
+ /// The analysis tool user interface should be capable of automatically formatting the parameter.
+ ///
+ public string? Target { get; set; }
+
+ ///
+ /// Gets or sets an optional argument expanding on exclusion criteria.
+ ///
+ ///
+ /// The property is an optional argument that specifies additional
+ /// exclusion where the literal metadata target is not sufficiently precise. For example,
+ /// the cannot be applied within a method,
+ /// and it may be desirable to suppress a violation against a statement in the method that will
+ /// give a rule violation, but not against all statements in the method.
+ ///
+ public string? MessageId { get; set; }
+
+ ///
+ /// Gets or sets the justification for suppressing the code analysis message.
+ ///
+ public string? Justification { get; set; }
+ }
+
+ ///
+ /// States a dependency that one member has on another.
+ ///
+ ///
+ /// This can be used to inform tooling of a dependency that is otherwise not evident purely from
+ /// metadata and IL, for example a member relied on via reflection.
+ ///
+ [AttributeUsage(
+ AttributeTargets.Constructor | AttributeTargets.Field | AttributeTargets.Method,
+ AllowMultiple = true, Inherited = false)]
+ internal sealed class DynamicDependencyAttribute : Attribute
+ {
+ ///
+ /// Initializes a new instance of the class
+ /// with the specified signature of a member on the same type as the consumer.
+ ///
+ /// The signature of the member depended on.
+ public DynamicDependencyAttribute(string memberSignature)
+ {
+ MemberSignature = memberSignature;
+ }
+
+ ///
+ /// Initializes a new instance of the class
+ /// with the specified signature of a member on a .
+ ///
+ /// The signature of the member depended on.
+ /// The containing .
+ public DynamicDependencyAttribute(string memberSignature, Type type)
+ {
+ MemberSignature = memberSignature;
+ Type = type;
+ }
+
+ ///
+ /// Initializes a new instance of the class
+ /// with the specified signature of a member on a type in an assembly.
+ ///
+ /// The signature of the member depended on.
+ /// The full name of the type containing the specified member.
+ /// The assembly name of the type containing the specified member.
+ public DynamicDependencyAttribute(string memberSignature, string typeName, string assemblyName)
+ {
+ MemberSignature = memberSignature;
+ TypeName = typeName;
+ AssemblyName = assemblyName;
+ }
+
+ ///
+ /// Initializes a new instance of the class
+ /// with the specified types of members on a .
+ ///
+ /// The types of members depended on.
+ /// The containing the specified members.
+ public DynamicDependencyAttribute(DynamicallyAccessedMemberTypes memberTypes, Type type)
+ {
+ MemberTypes = memberTypes;
+ Type = type;
+ }
+
+ ///
+ /// Initializes a new instance of the class
+ /// with the specified types of members on a type in an assembly.
+ ///
+ /// The types of members depended on.
+ /// The full name of the type containing the specified members.
+ /// The assembly name of the type containing the specified members.
+ public DynamicDependencyAttribute(DynamicallyAccessedMemberTypes memberTypes, string typeName, string assemblyName)
+ {
+ MemberTypes = memberTypes;
+ TypeName = typeName;
+ AssemblyName = assemblyName;
+ }
+
+ ///
+ /// Gets the signature of the member depended on.
+ ///
+ ///
+ /// Either must be a valid string or
+ /// must not equal , but not both.
+ ///
+ public string? MemberSignature { get; }
+
+ ///
+ /// Gets the which specifies the type
+ /// of members depended on.
+ ///
+ ///
+ /// Either must be a valid string or
+ /// must not equal , but not both.
+ ///
+ public DynamicallyAccessedMemberTypes MemberTypes { get; }
+
+ ///
+ /// Gets the containing the specified member.
+ ///
+ ///
+ /// If neither nor are specified,
+ /// the type of the consumer is assumed.
+ ///
+ public Type? Type { get; }
+
+ ///
+ /// Gets the full name of the type containing the specified member.
+ ///
+ ///
+ /// If neither nor are specified,
+ /// the type of the consumer is assumed.
+ ///
+ public string? TypeName { get; }
+
+ ///
+ /// Gets the assembly name of the specified type.
+ ///
+ ///
+ /// is only valid when is specified.
+ ///
+ public string? AssemblyName { get; }
+
+ ///
+ /// Gets or sets the condition in which the dependency is applicable, e.g. "DEBUG".
+ ///
+ public string? Condition { get; set; }
+ }
+
+ ///
+ /// Indicates that certain members on a specified are accessed dynamically,
+ /// for example through .
+ ///
+ ///
+ /// This allows tools to understand which members are being accessed during the execution
+ /// of a program.
+ ///
+ /// This attribute is valid on members whose type is or .
+ ///
+ /// When this attribute is applied to a location of type , the assumption is
+ /// that the string represents a fully qualified type name.
+ ///
+ /// When this attribute is applied to a class, interface, or struct, the members specified
+ /// can be accessed dynamically on instances returned from calling
+ /// on instances of that class, interface, or struct.
+ ///
+ /// If the attribute is applied to a method it's treated as a special case and it implies
+ /// the attribute should be applied to the "this" parameter of the method. As such the attribute
+ /// should only be used on instance methods of types assignable to System.Type (or string, but no methods
+ /// will use it there).
+ ///
+ [AttributeUsage(
+ AttributeTargets.Field | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter |
+ AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.Method |
+ AttributeTargets.Class | AttributeTargets.Interface | AttributeTargets.Struct,
+ Inherited = false)]
+ internal sealed class DynamicallyAccessedMembersAttribute : Attribute
+ {
+ ///
+ /// Initializes a new instance of the class
+ /// with the specified member types.
+ ///
+ /// The types of members dynamically accessed.
+ public DynamicallyAccessedMembersAttribute(DynamicallyAccessedMemberTypes memberTypes)
+ {
+ MemberTypes = memberTypes;
+ }
+
+ ///
+ /// Gets the which specifies the type
+ /// of members dynamically accessed.
+ ///
+ public DynamicallyAccessedMemberTypes MemberTypes { get; }
+ }
+
+ ///
+ /// Specifies the types of members that are dynamically accessed.
+ ///
+ /// This enumeration has a attribute that allows a
+ /// bitwise combination of its member values.
+ ///
+ [Flags]
+ internal enum DynamicallyAccessedMemberTypes
+ {
+ ///
+ /// Specifies no members.
+ ///
+ None = 0,
+
+ ///
+ /// Specifies the default, parameterless public constructor.
+ ///
+ PublicParameterlessConstructor = 0x0001,
+
+ ///
+ /// Specifies all public constructors.
+ ///
+ PublicConstructors = 0x0002 | PublicParameterlessConstructor,
+
+ ///
+ /// Specifies all non-public constructors.
+ ///
+ NonPublicConstructors = 0x0004,
+
+ ///
+ /// Specifies all public methods.
+ ///
+ PublicMethods = 0x0008,
+
+ ///
+ /// Specifies all non-public methods.
+ ///
+ NonPublicMethods = 0x0010,
+
+ ///
+ /// Specifies all public fields.
+ ///
+ PublicFields = 0x0020,
+
+ ///
+ /// Specifies all non-public fields.
+ ///
+ NonPublicFields = 0x0040,
+
+ ///
+ /// Specifies all public nested types.
+ ///
+ PublicNestedTypes = 0x0080,
+
+ ///
+ /// Specifies all non-public nested types.
+ ///
+ NonPublicNestedTypes = 0x0100,
+
+ ///
+ /// Specifies all public properties.
+ ///
+ PublicProperties = 0x0200,
+
+ ///
+ /// Specifies all non-public properties.
+ ///
+ NonPublicProperties = 0x0400,
+
+ ///
+ /// Specifies all public events.
+ ///
+ PublicEvents = 0x0800,
+
+ ///
+ /// Specifies all non-public events.
+ ///
+ NonPublicEvents = 0x1000,
+
+ ///
+ /// Specifies all interfaces implemented by the type.
+ ///
+ Interfaces = 0x2000,
+
+ ///
+ /// Specifies all members.
+ ///
+ All = ~None
+ }
+}
+
+#endif
diff --git a/dotnet/src/webdriver/JavaScriptEngine.cs b/dotnet/src/webdriver/JavaScriptEngine.cs
index b1a573490b9f4..72fcd4076181a 100644
--- a/dotnet/src/webdriver/JavaScriptEngine.cs
+++ b/dotnet/src/webdriver/JavaScriptEngine.cs
@@ -21,6 +21,7 @@
using OpenQA.Selenium.Internal;
using System;
using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.Linq;
@@ -34,6 +35,8 @@ namespace OpenQA.Selenium
///
/// Provides methods allowing the user to manage settings in the browser's JavaScript engine.
///
+ [RequiresUnreferencedCode("JavaScriptEngine is currently implemented with CDP. When it is implemented with BiDi, AOT will be supported")]
+ [RequiresDynamicCode("JavaScriptEngine is currently implemented with CDP. When it is implemented with BiDi, AOT will be supported.")]
public class JavaScriptEngine : IJavaScriptEngine
{
private const string MonitorBindingName = "__webdriver_attribute";
diff --git a/dotnet/src/webdriver/NetworkManager.cs b/dotnet/src/webdriver/NetworkManager.cs
index 6d7f15f63f7eb..766d07efb002e 100644
--- a/dotnet/src/webdriver/NetworkManager.cs
+++ b/dotnet/src/webdriver/NetworkManager.cs
@@ -20,6 +20,7 @@
using OpenQA.Selenium.DevTools;
using System;
using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
using System.Threading.Tasks;
#nullable enable
@@ -40,6 +41,8 @@ public class NetworkManager : INetwork
/// Initializes a new instance of the class.
///
/// The instance on which the network should be monitored.
+ [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "Warnings are added to StartMonitoring and StopMonitoring")]
+ [UnconditionalSuppressMessage("Trimming", "IL3050", Justification = "Warnings are added to StartMonitoring and StopMonitoring")]
public NetworkManager(IWebDriver driver)
{
// Use of Lazy means this exception won't be thrown until the user first
@@ -70,6 +73,8 @@ public NetworkManager(IWebDriver driver)
/// Asynchronously starts monitoring for network traffic.
///
/// A task that represents the asynchronous operation.
+ [RequiresUnreferencedCode("NetworkManager is currently implemented with CDP. When it is implemented with BiDi, AOT will be supported")]
+ [RequiresDynamicCode("NetworkManager is currently implemented with CDP. When it is implemented with BiDi, AOT will be supported.")]
public async Task StartMonitoring()
{
this.session.Value.Domains.Network.RequestPaused += OnRequestPaused;
@@ -84,6 +89,8 @@ public async Task StartMonitoring()
/// Asynchronously stops monitoring for network traffic.
///
/// A task that represents the asynchronous operation.
+ [RequiresUnreferencedCode("Network monitoring is currently implemented with CDP. When it is implemented with BiDi, AOT will be supported")]
+ [RequiresDynamicCode("Network monitoring is currently implemented with CDP. When it is implemented with BiDi, AOT will be supported.")]
public async Task StopMonitoring()
{
this.session.Value.Domains.Network.ResponsePaused -= OnResponsePaused;
diff --git a/dotnet/src/webdriver/Remote/RemoteWebDriver.cs b/dotnet/src/webdriver/Remote/RemoteWebDriver.cs
index cc63a718583b4..4d46ac8df39f9 100644
--- a/dotnet/src/webdriver/Remote/RemoteWebDriver.cs
+++ b/dotnet/src/webdriver/Remote/RemoteWebDriver.cs
@@ -427,6 +427,8 @@ public ReadOnlyCollection FindElementsByCssSelector(string cssSelec
/// Creates a session to communicate with a browser using a Developer Tools debugging protocol.
///
/// The active session to use to communicate with the Developer Tools debugging protocol.
+ [RequiresUnreferencedCode(DevToolsSession.CDP_AOTIncompatibilityMessage)]
+ [RequiresDynamicCode(DevToolsSession.CDP_AOTIncompatibilityMessage)]
public DevToolsSession GetDevToolsSession()
{
if (this.Capabilities.GetCapability(CapabilityType.BrowserName) is "firefox")
@@ -444,6 +446,8 @@ public DevToolsSession GetDevToolsSession()
/// Creates a session to communicate with a browser using a Developer Tools debugging protocol.
///
/// The active session to use to communicate with the Developer Tools debugging protocol.
+ [RequiresUnreferencedCode(DevToolsSession.CDP_AOTIncompatibilityMessage)]
+ [RequiresDynamicCode(DevToolsSession.CDP_AOTIncompatibilityMessage)]
public DevToolsSession GetDevToolsSession(DevToolsOptions options)
{
if (options is null)
@@ -500,6 +504,8 @@ public DevToolsSession GetDevToolsSession(DevToolsOptions options)
/// The specific version of the Developer Tools debugging protocol to use.
/// The active session to use to communicate with the Developer Tools debugging protocol.
[Obsolete("Use GetDevToolsSession(DevToolsOptions options)")]
+ [RequiresUnreferencedCode(DevToolsSession.CDP_AOTIncompatibilityMessage)]
+ [RequiresDynamicCode(DevToolsSession.CDP_AOTIncompatibilityMessage)]
public DevToolsSession GetDevToolsSession(int protocolVersion)
{
return GetDevToolsSession(new DevToolsOptions() { ProtocolVersion = protocolVersion });
@@ -588,6 +594,8 @@ public void DeleteDownloadableFiles()
///
/// Closes a DevTools session.
///
+ [RequiresUnreferencedCode(DevToolsSession.CDP_AOTIncompatibilityMessage)]
+ [RequiresDynamicCode(DevToolsSession.CDP_AOTIncompatibilityMessage)]
public void CloseDevToolsSession()
{
if (this.devToolsSession != null)
diff --git a/dotnet/src/webdriver/Response.cs b/dotnet/src/webdriver/Response.cs
index 8f643e7082809..8ee70c76250b3 100644
--- a/dotnet/src/webdriver/Response.cs
+++ b/dotnet/src/webdriver/Response.cs
@@ -172,6 +172,9 @@ public static Response FromErrorJson(string value)
/// Returns this object as a JSON-encoded string.
///
/// A JSON-encoded string representing this object.
+
+ [RequiresUnreferencedCode("Untyped JSON serialization is not trim- or AOT- safe.")]
+ [RequiresDynamicCode("Untyped JSON serialization is not trim- or AOT- safe.")]
public string ToJson()
{
return JsonSerializer.Serialize(this);
diff --git a/dotnet/src/webdriver/WebDriver.csproj b/dotnet/src/webdriver/WebDriver.csproj
index 0ee11dce27d67..1841379278363 100644
--- a/dotnet/src/webdriver/WebDriver.csproj
+++ b/dotnet/src/webdriver/WebDriver.csproj
@@ -42,6 +42,11 @@
true
+
+
+