Path: blob/trunk/dotnet/test/common/Environment/DriverFactory.cs
2868 views
// <copyright file="DriverFactory.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 OpenQA.Selenium.Chrome; using OpenQA.Selenium.Chromium; using OpenQA.Selenium.Edge; using OpenQA.Selenium.Firefox; using OpenQA.Selenium.IE; using OpenQA.Selenium.Safari; using System; using System.Collections.Generic; using System.IO; using System.Reflection; namespace OpenQA.Selenium.Environment; public class DriverFactory { string driverPath; string browserBinaryLocation; private Dictionary<Browser, Type> serviceTypes = new Dictionary<Browser, Type>(); private Dictionary<Browser, Type> optionsTypes = new Dictionary<Browser, Type>(); public DriverFactory(string driverPath, string browserBinaryLocation) { this.driverPath = driverPath; this.browserBinaryLocation = browserBinaryLocation; this.PopulateServiceTypes(); this.PopulateOptionsTypes(); } private void PopulateOptionsTypes() { this.optionsTypes[Browser.Chrome] = typeof(ChromeOptions); this.optionsTypes[Browser.Edge] = typeof(EdgeOptions); this.optionsTypes[Browser.Firefox] = typeof(FirefoxOptions); this.optionsTypes[Browser.IE] = typeof(InternetExplorerOptions); this.optionsTypes[Browser.Safari] = typeof(SafariOptions); } private void PopulateServiceTypes() { this.serviceTypes[Browser.Chrome] = typeof(ChromeDriverService); this.serviceTypes[Browser.Edge] = typeof(EdgeDriverService); this.serviceTypes[Browser.Firefox] = typeof(FirefoxDriverService); this.serviceTypes[Browser.IE] = typeof(InternetExplorerDriverService); this.serviceTypes[Browser.Safari] = typeof(SafariDriverService); } public event EventHandler<DriverStartingEventArgs> DriverStarting; public IWebDriver CreateDriver(Type driverType, bool logging = false) { return CreateDriverWithOptions(driverType, null, logging); } public IWebDriver CreateDriverWithOptions(Type driverType, DriverOptions driverOptions, bool logging = false) { Browser browser = Browser.All; DriverService service = null; DriverOptions options = null; bool enableLogging = logging; List<Type> constructorArgTypeList = new List<Type>(); IWebDriver driver = null; if (typeof(ChromeDriver).IsAssignableFrom(driverType)) { browser = Browser.Chrome; options = GetDriverOptions<ChromeOptions>(driverType, driverOptions); var chromeOptions = (ChromeOptions)options; chromeOptions.AddArguments("--no-sandbox", "--disable-dev-shm-usage"); service = CreateService<ChromeDriverService>(); if (!string.IsNullOrEmpty(this.browserBinaryLocation)) { ((ChromeOptions)options).BinaryLocation = this.browserBinaryLocation; } if (enableLogging) { ((ChromiumDriverService)service).EnableVerboseLogging = true; } } else if (typeof(EdgeDriver).IsAssignableFrom(driverType)) { browser = Browser.Edge; options = GetDriverOptions<EdgeOptions>(driverType, driverOptions); var edgeOptions = (EdgeOptions)options; edgeOptions.AddArguments("--no-sandbox", "--disable-dev-shm-usage"); service = CreateService<EdgeDriverService>(); if (!string.IsNullOrEmpty(this.browserBinaryLocation)) { ((EdgeOptions)options).BinaryLocation = this.browserBinaryLocation; } if (enableLogging) { ((ChromiumDriverService)service).EnableVerboseLogging = true; } } else if (typeof(InternetExplorerDriver).IsAssignableFrom(driverType)) { browser = Browser.IE; options = GetDriverOptions<InternetExplorerOptions>(driverType, driverOptions); service = CreateService<InternetExplorerDriverService>(); if (enableLogging) { ((InternetExplorerDriverService)service).LoggingLevel = InternetExplorerDriverLogLevel.Trace; } } else if (typeof(FirefoxDriver).IsAssignableFrom(driverType)) { browser = Browser.Firefox; options = GetDriverOptions<FirefoxOptions>(driverType, driverOptions); service = CreateService<FirefoxDriverService>(); if (!string.IsNullOrEmpty(this.browserBinaryLocation)) { ((FirefoxOptions)options).BinaryLocation = this.browserBinaryLocation; } if (enableLogging) { ((FirefoxDriverService)service).LogLevel = FirefoxDriverLogLevel.Trace; } } else if (typeof(SafariDriver).IsAssignableFrom(driverType)) { browser = Browser.Safari; options = GetDriverOptions<SafariOptions>(driverType, driverOptions); service = CreateService<SafariDriverService>(); } if (!String.IsNullOrEmpty(this.driverPath) && service != null) { service.DriverServicePath = Path.GetDirectoryName(this.driverPath); service.DriverServiceExecutableName = Path.GetFileName(this.driverPath); } this.OnDriverLaunching(service, options); if (browser != Browser.All) { constructorArgTypeList.Add(this.serviceTypes[browser]); constructorArgTypeList.Add(this.optionsTypes[browser]); ConstructorInfo ctorInfo = driverType.GetConstructor(constructorArgTypeList.ToArray()); if (ctorInfo != null) { return (IWebDriver)ctorInfo.Invoke(new object[] { service, options }); } } driver = (IWebDriver)Activator.CreateInstance(driverType); return driver; } protected void OnDriverLaunching(DriverService service, DriverOptions options) { if (this.DriverStarting != null) { DriverStartingEventArgs args = new DriverStartingEventArgs(service, options); this.DriverStarting(this, args); } } private T GetDriverOptions<T>(Type driverType, DriverOptions overriddenOptions) where T : DriverOptions, new() { T options = new T(); Type optionsType = typeof(T); PropertyInfo defaultOptionsProperty = driverType.GetProperty("DefaultOptions", BindingFlags.Public | BindingFlags.Static); if (defaultOptionsProperty != null && defaultOptionsProperty.PropertyType == optionsType) { options = (T)defaultOptionsProperty.GetValue(null, null); } if (overriddenOptions != null) { options.PageLoadStrategy = overriddenOptions.PageLoadStrategy; options.UnhandledPromptBehavior = overriddenOptions.UnhandledPromptBehavior; options.Proxy = overriddenOptions.Proxy; options.ScriptTimeout = overriddenOptions.ScriptTimeout; options.PageLoadTimeout = overriddenOptions.PageLoadTimeout; options.ImplicitWaitTimeout = overriddenOptions.ImplicitWaitTimeout; options.UseWebSocketUrl = overriddenOptions.UseWebSocketUrl; } return options; } private T MergeOptions<T>(object baseOptions, DriverOptions overriddenOptions) where T : DriverOptions, new() { // If the driver type has a static DefaultOptions property, // get the value of that property, which should be a valid // options of the generic type (T). Otherwise, create a new // instance of the browser-specific options class. T mergedOptions = new T(); if (baseOptions != null && baseOptions is T) { mergedOptions = (T)baseOptions; } if (overriddenOptions != null) { mergedOptions.PageLoadStrategy = overriddenOptions.PageLoadStrategy; mergedOptions.UnhandledPromptBehavior = overriddenOptions.UnhandledPromptBehavior; mergedOptions.Proxy = overriddenOptions.Proxy; } return mergedOptions; } private T CreateService<T>() where T : DriverService { T service = default(T); Type serviceType = typeof(T); MethodInfo createDefaultServiceMethod = serviceType.GetMethod("CreateDefaultService", BindingFlags.Public | BindingFlags.Static, null, new Type[] { }, null); if (createDefaultServiceMethod != null && createDefaultServiceMethod.ReturnType == serviceType) { service = (T)createDefaultServiceMethod.Invoke(null, new object[] { }); } return service; } }