Path: blob/trunk/dotnet/src/webdriver/DevTools/DevToolsDomains.cs
2885 views
// <copyright file="DevToolsDomains.cs" company="Selenium Committers"> // 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. // </copyright> using System; using System.Collections.Generic; namespace OpenQA.Selenium.DevTools; /// <summary> /// Interface providing version-independent implementations of operations available using the DevTools Protocol. /// </summary> public abstract class DevToolsDomains { // By default, we will look for a supported version within this // number of versions, as that will most likely still work. private const int DefaultVersionRange = 5; // This is the list of known supported DevTools version implementation. // When new versions are implemented for support, new types must be // added to this array and to the method below. private static int[] SupportedDevToolsVersions => [ 136, 138, 137, ]; private static DevToolsDomains? CreateDevToolsDomain(int protocolVersion, DevToolsSession session) => protocolVersion switch { 136 => new V136.V136Domains(session), 138 => new V138.V138Domains(session), 137 => new V137.V137Domains(session), _ => null }; /// <summary> /// Gets the version-specific domains for the DevTools session. This value must be cast to a version specific type to be at all useful. /// </summary> public abstract DevToolsSessionDomains VersionSpecificDomains { get; } /// <summary> /// Gets the object used for manipulating network information in the browser. /// </summary> public abstract Network Network { get; } /// <summary> /// Gets the object used for manipulating the browser's JavaScript execution. /// </summary> public abstract JavaScript JavaScript { get; } /// <summary> /// Gets the object used for manipulating DevTools Protocol targets. /// </summary> public abstract Target Target { get; } /// <summary> /// Gets the object used for manipulating the browser's logs. /// </summary> public abstract Log Log { get; } /// <summary> /// Initializes the supplied DevTools session's domains for the specified browser version. /// </summary> /// <param name="protocolVersion">The version of the DevTools Protocol to use.</param> /// <param name="session">The <see cref="DevToolsSession"/> for which to initialize the domains.</param> /// <returns>The <see cref="DevToolsDomains"/> object containing the version-specific domains.</returns> /// <exception cref="ArgumentException">If <paramref name="protocolVersion"/> is negative.</exception> /// <exception cref="WebDriverException">If the desired protocol version is not supported.</exception> public static DevToolsDomains InitializeDomains(int protocolVersion, DevToolsSession session) { return InitializeDomains(protocolVersion, session, DefaultVersionRange); } /// <summary> /// Initializes the supplied DevTools session's domains for the specified browser version within the specified number of versions. /// </summary> /// <param name="protocolVersion">The version of the DevTools Protocol to use.</param> /// <param name="session">The <see cref="DevToolsSession"/> for which to initialize the domains.</param> /// <param name="versionRange">The range of versions within which to match the provided version number. Defaults to 5 versions.</param> /// <returns>The <see cref="DevToolsDomains"/> object containing the version-specific domains.</returns> /// <exception cref="ArgumentException">If <paramref name="protocolVersion"/> is negative.</exception> /// <exception cref="WebDriverException">If the desired protocol version is not in the supported range.</exception> public static DevToolsDomains InitializeDomains(int protocolVersion, DevToolsSession session, int versionRange) { if (versionRange < 0) { throw new ArgumentException("Version range must be positive", nameof(versionRange)); } // Return fast on an exact match DevToolsDomains? domains = CreateDevToolsDomain(protocolVersion, session); if (domains is not null) { return domains; } return CreateFallbackDomain(protocolVersion, session, versionRange); } private static DevToolsDomains CreateFallbackDomain(int desiredVersion, DevToolsSession session, int versionRange) { // Get the list of supported versions and sort descending List<int> supportedVersions = new List<int>(SupportedDevToolsVersions); supportedVersions.Sort((first, second) => second.CompareTo(first)); foreach (int supportedVersion in supportedVersions) { // Match the version with the desired version within the // version range, using "The Price Is Right" style matching // (that is, closest without going over). if (desiredVersion >= supportedVersion && desiredVersion - supportedVersion < versionRange) { return CreateDevToolsDomain(supportedVersion, session)!; } } throw new WebDriverException($"DevTools version is not in the supported range. Desired version={desiredVersion}, range={versionRange}. Supported versions: {string.Join(", ", supportedVersions)}"); } }