Merge pull request #35 from unoplatform/dev/dr/Edge
feat(EdgeSupport): Add support for the chromium edge
This commit is contained in:
Коммит
9669fd2783
|
@ -13,7 +13,6 @@
|
|||
|
||||
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||
*.userprefs
|
||||
launchSettings.json
|
||||
|
||||
# Build results
|
||||
[Dd]ebug[-\w]*/
|
||||
|
|
21
.vsts-ci.yml
21
.vsts-ci.yml
|
@ -47,17 +47,11 @@ jobs:
|
|||
displayName: Use GitVersion
|
||||
|
||||
- task: UseDotNet@2
|
||||
displayName: 'Use .NET Core SDK 5.0.101'
|
||||
inputs:
|
||||
packageType: sdk
|
||||
version: 5.0.101
|
||||
|
||||
- task: UseDotNet@2
|
||||
displayName: 'Use .NET Core SDK 6.0.401'
|
||||
displayName: 'Use .NET SDK'
|
||||
retryCountOnTaskFailure: 3
|
||||
inputs:
|
||||
packageType: sdk
|
||||
version: 6.0.401
|
||||
version: 7.0.302
|
||||
|
||||
- task: MSBuild@1
|
||||
inputs:
|
||||
|
@ -110,16 +104,11 @@ jobs:
|
|||
clean: true
|
||||
|
||||
- task: UseDotNet@2
|
||||
displayName: 'Use .NET Core SDK 5.0.101'
|
||||
displayName: 'Use .NET SDK'
|
||||
retryCountOnTaskFailure: 3
|
||||
inputs:
|
||||
packageType: sdk
|
||||
version: 5.0.101
|
||||
|
||||
- task: UseDotNet@2
|
||||
displayName: 'Use .NET Core SDK 6.0.401'
|
||||
inputs:
|
||||
packageType: sdk
|
||||
version: 6.0.401
|
||||
version: 7.0.302
|
||||
|
||||
- bash: |
|
||||
chmod +x build/wasm-uitest-run.sh
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
<!-- Force embedded roslyn generators -->
|
||||
<UnoUIUseRoslynSourceGenerators>true</UnoUIUseRoslynSourceGenerators>
|
||||
<!--<LangVersion>10.0</LangVersion>-->
|
||||
</PropertyGroup>
|
||||
|
||||
<Choose>
|
||||
|
|
|
@ -4,6 +4,7 @@ using System.Linq;
|
|||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Uno.UITest.Helpers.Queries;
|
||||
using Uno.UITests.Helpers;
|
||||
|
||||
namespace Sample.UITests
|
||||
{
|
||||
|
@ -15,5 +16,7 @@ namespace Sample.UITests
|
|||
public readonly static string iOSDeviceNameOrId = "iPad Pro (12.9-inch) (5th generation)";
|
||||
|
||||
public readonly static Platform CurrentPlatform = Platform.Browser;
|
||||
|
||||
public readonly static Browser WebAssemblyBrowser = Browser.Chrome;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,8 @@ namespace Sample.UITests
|
|||
[Test]
|
||||
public void DragBorder01()
|
||||
{
|
||||
App.Screenshot("home screen");
|
||||
|
||||
Query testSelector = q => q.Marked("DragCoordinates 01");
|
||||
|
||||
Query rootCanvas = q => q.Marked("rootCanvas");
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net47</TargetFramework>
|
||||
<LangVersion>7.3</LangVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
@ -40,6 +40,7 @@ namespace Sample.UITests
|
|||
AppInitializer.TestEnvironment.AndroidAppName = Constants.AndroidAppName;
|
||||
AppInitializer.TestEnvironment.iOSDeviceNameOrId = Constants.iOSDeviceNameOrId;
|
||||
AppInitializer.TestEnvironment.CurrentPlatform = Constants.CurrentPlatform;
|
||||
AppInitializer.TestEnvironment.WebAssemblyBrowser = Constants.WebAssemblyBrowser;
|
||||
|
||||
#if DEBUG
|
||||
AppInitializer.TestEnvironment.WebAssemblyHeadless = false;
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
"IIS Express": {
|
||||
"commandName": "IISExpress",
|
||||
"launchBrowser": true,
|
||||
"inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
|
@ -18,10 +19,12 @@
|
|||
"Sample.Wasm": {
|
||||
"commandName": "Project",
|
||||
"launchBrowser": true,
|
||||
"inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}",
|
||||
"launchUrl": "http://localhost:55932/",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
},
|
||||
"applicationUrl": "http://localhost:5000"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,43 +1,49 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<WasmHead>true</WasmHead>
|
||||
<DefineConstants>$(DefineConstants);__WASM__</DefineConstants>
|
||||
<NoWarn>NU1701</NoWarn>
|
||||
<UnoUIUseRoslynSourceGenerators>true</UnoUIUseRoslynSourceGenerators>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<IsUiAutomationMappingEnabled>true</IsUiAutomationMappingEnabled>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="..\Sample.UWP\Assets\*.png" Link="Assets\%(FileName)%(Extension)" />
|
||||
<Content Include="Fonts\winjs-symbols.woff2" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="WasmCSS\Fonts.css" />
|
||||
<EmbeddedResource Include="WasmScripts\AppManifest.js" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<LinkerDescriptor Include="LinkerConfig.xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<!--
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<WasmHead>true</WasmHead>
|
||||
<DefineConstants>$(DefineConstants);__WASM__</DefineConstants>
|
||||
<NoWarn>NU1701</NoWarn>
|
||||
<UnoUIUseRoslynSourceGenerators>true</UnoUIUseRoslynSourceGenerators>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<IsUiAutomationMappingEnabled>true</IsUiAutomationMappingEnabled>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)'=='Debug'">
|
||||
<MonoRuntimeDebuggerEnabled>true</MonoRuntimeDebuggerEnabled>
|
||||
<DefineConstants>$(DefineConstants);TRACE;DEBUG</DefineConstants>
|
||||
<DebugType>portable</DebugType>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="..\Sample.UWP\Assets\*.png" Link="Assets\%(FileName)%(Extension)" />
|
||||
<Content Include="Fonts\winjs-symbols.woff2" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="WasmCSS\Fonts.css" />
|
||||
<EmbeddedResource Include="WasmScripts\AppManifest.js" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<LinkerDescriptor Include="LinkerConfig.xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<!--
|
||||
This item group is required by the project templace because of the
|
||||
new SDK-Style project, otherwise some files are not aded automatically.
|
||||
|
||||
You can safely remove this ItemGroup completely.
|
||||
-->
|
||||
<Compile Remove="Program.cs" />
|
||||
<Compile Include="Program.cs" />
|
||||
<Content Include="LinkerConfig.xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Uno.UI.WebAssembly" Version="3.7.6" />
|
||||
<PackageReference Include="Uno.Wasm.Bootstrap" Version="7.0.20" />
|
||||
<PackageReference Include="Uno.Wasm.Bootstrap.DevServer" Version="7.0.20" />
|
||||
<PackageReference Include="Microsoft.Windows.Compatibility" Version="5.0.1" />
|
||||
</ItemGroup>
|
||||
<Import Project="..\Sample.Shared\Sample.Shared.projitems" Label="Shared" Condition="Exists('..\Sample.Shared\Sample.Shared.projitems')" />
|
||||
<Compile Remove="Program.cs" />
|
||||
<Compile Include="Program.cs" />
|
||||
<Content Include="LinkerConfig.xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Uno.UI.WebAssembly" Version="3.7.6" />
|
||||
<PackageReference Include="Uno.Wasm.Bootstrap" Version="7.0.20" />
|
||||
<PackageReference Include="Uno.Wasm.Bootstrap.DevServer" Version="7.0.20" />
|
||||
<PackageReference Include="Microsoft.Windows.Compatibility" Version="5.0.1" />
|
||||
</ItemGroup>
|
||||
<Import Project="..\Sample.Shared\Sample.Shared.projitems" Label="Shared" Condition="Exists('..\Sample.Shared\Sample.Shared.projitems')" />
|
||||
</Project>
|
||||
|
|
|
@ -179,29 +179,38 @@ namespace Uno.UITests.Helpers
|
|||
{
|
||||
var configurator = Uno.UITest.Selenium.ConfigureApp
|
||||
.WebAssembly
|
||||
.Uri(new Uri(TestEnvironment.WebAssemblyDefaultUri));
|
||||
|
||||
.Uri(new Uri(TestEnvironment.WebAssemblyDefaultUri))
|
||||
.UsingBrowser(TestEnvironment.WebAssemblyBrowser.ToString());
|
||||
|
||||
if(!string.IsNullOrEmpty(TestEnvironment.ChromeDriverPath))
|
||||
{
|
||||
configurator = configurator.ChromeDriverLocation(
|
||||
Path.Combine(TestContext.CurrentContext.TestDirectory,
|
||||
TestEnvironment.ChromeDriverPath.Replace('\\', Path.DirectorySeparatorChar)));
|
||||
var driverPath = Path.Combine(
|
||||
TestContext.CurrentContext.TestDirectory,
|
||||
TestEnvironment.ChromeDriverPath.Replace('\\', Path.DirectorySeparatorChar));
|
||||
configurator = configurator.DriverPath(driverPath);
|
||||
}
|
||||
else if(!string.IsNullOrEmpty(TestEnvironment.SeleniumDriverPath))
|
||||
{
|
||||
var driverPath = Path.Combine(
|
||||
TestContext.CurrentContext.TestDirectory,
|
||||
TestEnvironment.SeleniumDriverPath.Replace('\\', Path.DirectorySeparatorChar));
|
||||
configurator = configurator.DriverPath(driverPath);
|
||||
}
|
||||
|
||||
if(!TestEnvironment.WebAssemblyHeadless)
|
||||
if(TestEnvironment.WebAssemblyHeadless)
|
||||
{
|
||||
configurator = configurator
|
||||
.Headless(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
configurator = configurator
|
||||
.Headless(false)
|
||||
.SeleniumArgument("--remote-debugging-port=9222");
|
||||
}
|
||||
else
|
||||
{
|
||||
configurator = configurator
|
||||
.Headless(true);
|
||||
}
|
||||
|
||||
_currentApp = configurator.ScreenShotsPath(TestContext.CurrentContext.TestDirectory)
|
||||
_currentApp = configurator
|
||||
.ScreenShotsPath(TestContext.CurrentContext.TestDirectory)
|
||||
.StartApp();
|
||||
|
||||
return _currentApp;
|
||||
|
|
|
@ -45,9 +45,26 @@ namespace Uno.UITests.Helpers
|
|||
/// </remarks>
|
||||
public string ChromeDriverPath { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Defines the location of selenium driver.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// If not defined, the test engine will select the version based on
|
||||
/// the currently installed browsers version.
|
||||
/// </remarks>
|
||||
public string SeleniumDriverPath { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Defines if the browser tests are running in chrome without a window.
|
||||
/// </summary>
|
||||
public bool WebAssemblyHeadless { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Defines the browser to use for the Web platform. Cf. remarks about compatibility
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Note that all browser does not supports all options defined here. For instance Edge does support only the <see cref="SeleniumDriverPath"/>.
|
||||
/// </remarks>
|
||||
public Browser WebAssemblyBrowser { get; set; } = Browser.Chrome;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace Uno.UITests.Helpers
|
||||
{
|
||||
/// <summary>
|
||||
/// Supported web browsers for UI tests
|
||||
/// </summary>
|
||||
public enum Browser
|
||||
{
|
||||
Chrome,
|
||||
|
||||
/// <summary>
|
||||
/// The **CHROMIUM Based** Edge web browser
|
||||
/// </summary>
|
||||
Edge
|
||||
}
|
||||
}
|
|
@ -1,64 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Uno.UITest.Selenium
|
||||
{
|
||||
public class ChromeAppConfigurator
|
||||
{
|
||||
internal string ChromeDriverPath { get; private set; }
|
||||
internal Uri SiteUri { get; private set; }
|
||||
internal string InternalScreenShotsPath { get; private set; } = "";
|
||||
internal bool InternalHeadless { get; private set; } = true;
|
||||
internal int InternalWindowWidth { get; private set; } = 1024;
|
||||
internal int InternalWindowHeight { get; private set; } = 768;
|
||||
internal string InternalBrowserBinaryPath { get; private set; }
|
||||
internal List<string> InternalSeleniumArgument = new List<string>();
|
||||
internal bool InternalDetectDockerEnvironment = true;
|
||||
|
||||
public ChromeAppConfigurator()
|
||||
{
|
||||
}
|
||||
|
||||
public ChromeAppConfigurator Uri(Uri uri) { SiteUri = uri; return this; }
|
||||
|
||||
public ChromeAppConfigurator ChromeDriverLocation(string chromeDriverPath) { ChromeDriverPath = chromeDriverPath; return this; }
|
||||
|
||||
public ChromeAppConfigurator ScreenShotsPath(string path) { InternalScreenShotsPath = path; return this; }
|
||||
|
||||
public ChromeAppConfigurator BrowserBinaryPath(string path) { InternalBrowserBinaryPath = path; return this; }
|
||||
|
||||
/// <summary>
|
||||
/// This parameters allows to provide a set of additional parameters to be provided to the WebDriver.
|
||||
/// </summary>
|
||||
public ChromeAppConfigurator SeleniumArgument(string argument) { InternalSeleniumArgument.Add(argument); return this; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Enables the detection of the docker environment to configure the WebDriver accordingly. Enabled by default.
|
||||
/// </summary>
|
||||
public ChromeAppConfigurator DetectDockerEnvironment(bool enabled) { InternalDetectDockerEnvironment = enabled; return this; }
|
||||
|
||||
/// <summary>
|
||||
/// Runs the browser as headless. Defaults to true.
|
||||
/// </summary>
|
||||
/// <param name="isHeadless"></param>
|
||||
/// <returns></returns>
|
||||
public ChromeAppConfigurator Headless(bool isHeadless) { InternalHeadless = isHeadless; return this; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Sets the window size. Defaults to 1024x768
|
||||
/// </summary>
|
||||
/// <param name="width"></param>
|
||||
/// <param name="height"></param>
|
||||
/// <returns></returns>
|
||||
public ChromeAppConfigurator WindowSize(int width, int height)
|
||||
{
|
||||
InternalWindowWidth = width;
|
||||
InternalWindowHeight = height;
|
||||
return this;
|
||||
}
|
||||
|
||||
public IApp StartApp() => new SeleniumApp(this);
|
||||
}
|
||||
}
|
|
@ -6,7 +6,6 @@ namespace Uno.UITest.Selenium
|
|||
{
|
||||
public static class ConfigureApp
|
||||
{
|
||||
public static ChromeAppConfigurator WebAssembly =>
|
||||
new ChromeAppConfigurator();
|
||||
public static SeleniumAppConfigurator WebAssembly => new SeleniumAppConfigurator();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.Json.Serialization;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Uno.UITest.Selenium.Models
|
||||
{
|
||||
|
||||
// Models generated by json2csharp.com from https://googlechromelabs.github.io/chrome-for-testing/known-good-versions-with-downloads.json
|
||||
public class Chrome
|
||||
{
|
||||
[JsonPropertyName("platform")]
|
||||
public string Platform { get; set; }
|
||||
|
||||
[JsonPropertyName("url")]
|
||||
public string Url { get; set; }
|
||||
}
|
||||
|
||||
public class Chromedriver
|
||||
{
|
||||
[JsonPropertyName("platform")]
|
||||
public string Platform { get; set; }
|
||||
|
||||
[JsonPropertyName("url")]
|
||||
public string Url { get; set; }
|
||||
}
|
||||
|
||||
public class Downloads
|
||||
{
|
||||
[JsonPropertyName("chrome")]
|
||||
public Chrome[] Chrome { get; set; }
|
||||
|
||||
[JsonPropertyName("chromedriver")]
|
||||
public Chromedriver[] Chromedriver { get; set; }
|
||||
}
|
||||
|
||||
public class Root
|
||||
{
|
||||
[JsonPropertyName("timestamp")]
|
||||
public DateTime? Timestamp { get; set; }
|
||||
|
||||
[JsonPropertyName("versions")]
|
||||
public ChromeVersion[] Versions { get; set; }
|
||||
}
|
||||
|
||||
public class ChromeVersion
|
||||
{
|
||||
[JsonPropertyName("version")]
|
||||
public string Version { get; set; }
|
||||
|
||||
[JsonPropertyName("revision")]
|
||||
public string Revision { get; set; }
|
||||
|
||||
[JsonPropertyName("downloads")]
|
||||
public Downloads Downloads { get; set; }
|
||||
}
|
||||
|
||||
}
|
|
@ -3,15 +3,12 @@ using System.Collections.Generic;
|
|||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Security.Policy;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using OpenQA.Selenium;
|
||||
using OpenQA.Selenium.Chrome;
|
||||
using OpenQA.Selenium.Chromium;
|
||||
using OpenQA.Selenium.Interactions;
|
||||
using OpenQA.Selenium.Remote;
|
||||
using static System.Math;
|
||||
|
@ -20,69 +17,14 @@ namespace Uno.UITest.Selenium
|
|||
{
|
||||
public partial class SeleniumApp : IApp
|
||||
{
|
||||
private const string UNO_UITEST_DRIVERPATH_CHROME = "UNO_UITEST_DRIVERPATH_CHROME";
|
||||
|
||||
|
||||
private readonly ChromeDriver _driver;
|
||||
private string _screenShotPath;
|
||||
private readonly ChromiumDriver _driver;
|
||||
private readonly string _screenShotPath;
|
||||
private readonly TimeSpan DefaultRetry = TimeSpan.FromMilliseconds(500);
|
||||
private readonly TimeSpan DefaultTimeout = TimeSpan.FromMinutes(1);
|
||||
|
||||
|
||||
public SeleniumApp(ChromeAppConfigurator config)
|
||||
public SeleniumApp(ChromiumDriver driver, string screenShotPath)
|
||||
{
|
||||
var targetUri = GetEnvironmentVariable("UNO_UITEST_TARGETURI", config.SiteUri.OriginalString);
|
||||
var driverPath = GetEnvironmentVariable(UNO_UITEST_DRIVERPATH_CHROME, config.ChromeDriverPath);
|
||||
var screenShotPath = GetEnvironmentVariable("UNO_UITEST_SCREENSHOT_PATH", config.InternalScreenShotsPath);
|
||||
var chromeBinPath = GetEnvironmentVariable("UNO_UITEST_CHROME_BINARY_PATH", config.InternalBrowserBinaryPath);
|
||||
|
||||
var options = new ChromeOptions();
|
||||
|
||||
if(config.InternalHeadless)
|
||||
{
|
||||
options.AddArguments("--no-sandbox");
|
||||
options.AddArguments("--disable-dev-shm-usage");
|
||||
options.AddArgument("headless");
|
||||
}
|
||||
|
||||
options.AddArgument($"window-size={config.InternalWindowWidth}x{config.InternalWindowHeight}");
|
||||
|
||||
if(config.InternalDetectDockerEnvironment)
|
||||
{
|
||||
if(File.Exists("/.dockerenv"))
|
||||
{
|
||||
// When running under docker, ports bindings may not work properly
|
||||
// as the current local host may not be detected properly by the web driver
|
||||
// causing errors like this one:
|
||||
//
|
||||
// [SEVERE]: bind() returned an error, errno=99: Cannot assign requested address (99)
|
||||
//
|
||||
// When InternalDetectDockerEnvironment is set, tell the daemon to listen on
|
||||
// all available interfaces
|
||||
Console.WriteLine($"Container mode enabled, adding whitelisted-ips");
|
||||
options.AddArguments("--whitelisted-ips");
|
||||
}
|
||||
}
|
||||
|
||||
foreach(var arg in config.InternalSeleniumArgument)
|
||||
{
|
||||
options.AddArguments(arg);
|
||||
}
|
||||
|
||||
if(!string.IsNullOrEmpty(chromeBinPath))
|
||||
{
|
||||
options.BinaryLocation = chromeBinPath;
|
||||
}
|
||||
|
||||
if(string.IsNullOrEmpty(driverPath))
|
||||
{
|
||||
driverPath = TryDownloadChromeDriver();
|
||||
}
|
||||
|
||||
options.SetLoggingPreference(LogType.Browser, LogLevel.All);
|
||||
|
||||
_driver = new ChromeDriver(driverPath, options);
|
||||
_driver.Url = targetUri;
|
||||
_driver = driver;
|
||||
_screenShotPath = screenShotPath;
|
||||
}
|
||||
|
||||
|
@ -92,145 +34,7 @@ namespace Uno.UITest.Selenium
|
|||
.Where(entry => afterDate == null || entry.Timestamp > afterDate)
|
||||
.Select(entry => new SeleniumLogEntry(entry));
|
||||
|
||||
private string TryDownloadChromeDriver()
|
||||
{
|
||||
if(Environment.OSVersion.Platform == PlatformID.Win32NT)
|
||||
{
|
||||
var chromePath = $@"{Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86)}\Google\Chrome\Application\chrome.exe";
|
||||
// Chrome might be installed in C:\Program Files\Google...
|
||||
// If file doesn't exist, check there.
|
||||
if(!File.Exists(chromePath))
|
||||
{
|
||||
// Using environment variable here since EnvironMent.SpecialFolder.ProgramFiles resolves to the X86
|
||||
// variant depending on the executable architecture. The path variable always evaluates to the correct path though.
|
||||
chromePath = $@"{Environment.GetEnvironmentVariable("ProgramW6432")}\Google\Chrome\Application\chrome.exe";
|
||||
}
|
||||
chromePath = chromePath.Replace("\\", "\\\\");
|
||||
|
||||
var process = new Process();
|
||||
process.StartInfo.FileName = "wmic.exe";
|
||||
process.StartInfo.Arguments = $@"datafile where name=""{chromePath}"" get Version /value";
|
||||
process.StartInfo.UseShellExecute = false;
|
||||
process.StartInfo.RedirectStandardOutput = true;
|
||||
process.StartInfo.RedirectStandardError = true;
|
||||
process.Start();
|
||||
|
||||
var wincOutput = process.StandardOutput.ReadToEnd();
|
||||
var chromeRawVersion = wincOutput.Split('=').LastOrDefault()?.Trim();
|
||||
|
||||
if(Version.TryParse(chromeRawVersion, out var chromeVersion))
|
||||
{
|
||||
var driverLocalPath = Path.Combine(Path.GetTempPath(), "Uno.UITests", "ChromeDriver", chromeVersion.ToString());
|
||||
Directory.CreateDirectory(driverLocalPath);
|
||||
|
||||
var driverPath = Path.Combine(driverLocalPath, "chromedriver.exe");
|
||||
|
||||
if(!File.Exists(driverPath))
|
||||
{
|
||||
// Chrome driver selection: http://chromedriver.chromium.org/downloads/version-selection
|
||||
|
||||
var chromeDriverLatestVersionUri = $"https://chromedriver.storage.googleapis.com/LATEST_RELEASE_{chromeVersion.Major}";
|
||||
|
||||
Console.WriteLine($"Fetching Chrome driver version for Chrome [{chromeRawVersion}]");
|
||||
#if NET6_0_OR_GREATER
|
||||
var driverVersion = Task.Run(async () =>
|
||||
{
|
||||
using var client = new HttpClient();
|
||||
return await client.GetStringAsync(chromeDriverLatestVersionUri);
|
||||
}).Result;
|
||||
#else
|
||||
var driverVersion = new WebClient().DownloadString(chromeDriverLatestVersionUri);
|
||||
#endif
|
||||
|
||||
var chromeDriverVersionUri = $"https://chromedriver.storage.googleapis.com/{driverVersion}/chromedriver_win32.zip";
|
||||
|
||||
var tempZipFileName = Path.GetTempFileName();
|
||||
|
||||
try
|
||||
{
|
||||
Console.WriteLine($"Downloading Chrome driver from [{chromeDriverVersionUri}]");
|
||||
#if NET6_0_OR_GREATER
|
||||
Task.Run(async () =>
|
||||
{
|
||||
using var client = new HttpClient();
|
||||
using var response = await client.GetAsync(chromeDriverVersionUri);
|
||||
if(!response.IsSuccessStatusCode)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var fileInfo = new FileInfo(tempZipFileName);
|
||||
if(!fileInfo.Directory.Exists)
|
||||
{
|
||||
fileInfo.Directory.Create();
|
||||
}
|
||||
if(fileInfo.Exists)
|
||||
{
|
||||
fileInfo.Delete();
|
||||
}
|
||||
|
||||
using var writer = fileInfo.OpenWrite();
|
||||
using var responseStream = await response.Content.ReadAsStreamAsync();
|
||||
await responseStream.CopyToAsync(writer);
|
||||
}).Wait();
|
||||
#else
|
||||
new WebClient().DownloadFile(chromeDriverVersionUri, tempZipFileName);
|
||||
#endif
|
||||
|
||||
using(var zipFile = ZipFile.OpenRead(tempZipFileName))
|
||||
{
|
||||
zipFile.GetEntry("chromedriver.exe").ExtractToFile(driverPath, true);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if(File.Exists(tempZipFileName))
|
||||
{
|
||||
File.Delete(tempZipFileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Path.GetDirectoryName(driverPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NotSupportedException($"Unable to determine the chrome driver version. The used path was [{chromePath}], found [{chromeVersion}].");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NotSupportedException($"Unable to determine the chrome driver location. Use the {UNO_UITEST_DRIVERPATH_CHROME} environment variable.");
|
||||
}
|
||||
}
|
||||
|
||||
private string GetEnvironmentVariable(string variableName, string defaultValue)
|
||||
{
|
||||
var value = Environment.GetEnvironmentVariable(variableName);
|
||||
|
||||
var hasValue = !string.IsNullOrWhiteSpace(value);
|
||||
|
||||
if(hasValue)
|
||||
{
|
||||
Console.WriteLine($"Overriding value with {variableName} = {value}");
|
||||
}
|
||||
|
||||
return hasValue ? value : defaultValue;
|
||||
}
|
||||
|
||||
private bool GetEnvironmentVariable(string variableName, bool defaultValue)
|
||||
{
|
||||
var value = Environment.GetEnvironmentVariable(variableName);
|
||||
|
||||
var hasValue = bool.TryParse(value, out var varValue);
|
||||
|
||||
if(hasValue)
|
||||
{
|
||||
Console.WriteLine($"Overriding value with {variableName} = {value}");
|
||||
}
|
||||
|
||||
return hasValue ? varValue : defaultValue;
|
||||
}
|
||||
public static SeleniumDriverManager SelectedBrowser { get; set; }
|
||||
|
||||
void PerformActions(Action<Actions> action)
|
||||
{
|
||||
|
@ -490,7 +294,6 @@ namespace Uno.UITest.Selenium
|
|||
|
||||
void IApp.TapCoordinates(float x, float y)
|
||||
{
|
||||
|
||||
PerformActions(a => a
|
||||
.MoveToElement(_driver.FindElement(By.TagName("body")), 0, 0)
|
||||
.MoveByOffset((int)x, (int)y)
|
||||
|
@ -680,6 +483,5 @@ namespace Uno.UITest.Selenium
|
|||
|
||||
throw new InvalidOperationException($"Invalid query results");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,237 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using OpenQA.Selenium.Chrome;
|
||||
using OpenQA.Selenium.Chromium;
|
||||
using OpenQA.Selenium.Edge;
|
||||
using OpenQA.Selenium.Remote;
|
||||
|
||||
namespace Uno.UITest.Selenium
|
||||
{
|
||||
public class SeleniumAppConfigurator
|
||||
{
|
||||
internal const string UNO_UITEST_DRIVER_PATH = "UNO_UITEST_DRIVER_PATH";
|
||||
|
||||
private string _browser;
|
||||
private Uri SiteUri { get; set; }
|
||||
private string InternalScreenShotsPath { get; set; } = "";
|
||||
private string InternalDriverPath { get; set; }
|
||||
private string InternalBrowserPath { get; set; }
|
||||
private bool InternalHeadless { get; set; } = true;
|
||||
private int InternalWindowWidth { get; set; } = 1024;
|
||||
private int InternalWindowHeight { get; set; } = 768;
|
||||
private List<string> InternalSeleniumArgument = new List<string>();
|
||||
private bool InternalDetectDockerEnvironment = true;
|
||||
|
||||
#region Fluent declaration
|
||||
public SeleniumAppConfigurator UsingBrowser(string browser)
|
||||
{
|
||||
_browser = browser;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SeleniumAppConfigurator Uri(Uri uri)
|
||||
{
|
||||
SiteUri = uri;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SeleniumAppConfigurator ScreenShotsPath(string path)
|
||||
{
|
||||
InternalScreenShotsPath = path;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SeleniumAppConfigurator BrowserBinaryPath(string path)
|
||||
{
|
||||
InternalBrowserPath = path;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SeleniumAppConfigurator BrowserPath(string path)
|
||||
{
|
||||
InternalBrowserPath = path;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SeleniumAppConfigurator DriverPath(string driverPath)
|
||||
{
|
||||
InternalDriverPath = driverPath;
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This parameters allows to provide a set of additional parameters to be provided to the WebDriver.
|
||||
/// </summary>
|
||||
public SeleniumAppConfigurator SeleniumArgument(string argument)
|
||||
{
|
||||
InternalSeleniumArgument.Add(argument);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Enables the detection of the docker environment to configure the WebDriver accordingly. Enabled by default.
|
||||
/// </summary>
|
||||
public SeleniumAppConfigurator DetectDockerEnvironment(bool enabled)
|
||||
{
|
||||
InternalDetectDockerEnvironment = enabled;
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Runs the browser as headless. Defaults to true.
|
||||
/// </summary>
|
||||
/// <param name="isHeadless"></param>
|
||||
/// <returns></returns>
|
||||
public SeleniumAppConfigurator Headless(bool isHeadless)
|
||||
{
|
||||
InternalHeadless = isHeadless;
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the window size. Defaults to 1024x768
|
||||
/// </summary>
|
||||
/// <param name="width"></param>
|
||||
/// <param name="height"></param>
|
||||
/// <returns></returns>
|
||||
public SeleniumAppConfigurator WindowSize(int width, int height)
|
||||
{
|
||||
InternalWindowWidth = width;
|
||||
InternalWindowHeight = height;
|
||||
return this;
|
||||
}
|
||||
#endregion
|
||||
|
||||
public IApp StartApp()
|
||||
{
|
||||
var targetUri = GetEnvironmentVariable("UNO_UITEST_TARGETURI", SiteUri.OriginalString);
|
||||
var screenShotPath = GetEnvironmentVariable("UNO_UITEST_SCREENSHOT_PATH", InternalScreenShotsPath);
|
||||
var browser = GetEnvironmentVariable("UNO_UITEST_BROWSER", _browser);
|
||||
var browserPath = GetEnvironmentVariable("UNO_UITEST_BROWSER_PATH", InternalBrowserPath);
|
||||
var driverPath = GetEnvironmentVariable(UNO_UITEST_DRIVER_PATH, InternalDriverPath);
|
||||
|
||||
ChromiumDriver driver;
|
||||
switch(browser?.ToUpperInvariant())
|
||||
{
|
||||
case "EDGE":
|
||||
driver = GetEdgeDriver(browserPath, driverPath);
|
||||
break;
|
||||
|
||||
case "CHROME":
|
||||
driver = GetChromeDriver(browserPath, driverPath);
|
||||
break;
|
||||
|
||||
default:
|
||||
if(browserPath?.Contains("edge") ?? driverPath?.Contains("edge") ?? false)
|
||||
{
|
||||
driver = GetEdgeDriver(browserPath, driverPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
driver = GetChromeDriver(browserPath, driverPath);
|
||||
}
|
||||
break;
|
||||
}
|
||||
driver.Url = targetUri;
|
||||
|
||||
return new SeleniumApp(driver, screenShotPath);
|
||||
}
|
||||
|
||||
protected ChromiumDriver GetChromeDriver(string browserPath = null, string driverPath = null)
|
||||
{
|
||||
// For backward compatibility, we give priority to the "CHROME" specific env. variables
|
||||
driverPath = GetEnvironmentVariable("UNO_UITEST_DRIVERPATH_CHROME", driverPath);
|
||||
browserPath = GetEnvironmentVariable("UNO_UITEST_CHROME_BINARY_PATH", browserPath);
|
||||
|
||||
var options = new ChromeOptions();
|
||||
ApplyOptions(options, browserPath);
|
||||
|
||||
var driver = string.IsNullOrEmpty(driverPath)
|
||||
? SeleniumDriverManager.Chrome.FromChromePath(browserPath, options)
|
||||
: SeleniumDriverManager.Chrome.FromDriverPath(driverPath, options);
|
||||
|
||||
return driver;
|
||||
}
|
||||
|
||||
protected ChromiumDriver GetEdgeDriver(string browserPath = null, string driverPath = null)
|
||||
{
|
||||
var options = new EdgeOptions();
|
||||
ApplyOptions(options, browserPath);
|
||||
|
||||
var driver = string.IsNullOrEmpty(driverPath)
|
||||
? SeleniumDriverManager.Edge.FromEdgePath(browserPath, options)
|
||||
: SeleniumDriverManager.Edge.FromDriverPath(driverPath, options);
|
||||
|
||||
return driver;
|
||||
}
|
||||
|
||||
private void ApplyOptions(ChromiumOptions options, string browserPath)
|
||||
{
|
||||
if(InternalHeadless)
|
||||
{
|
||||
options.AddArguments("--no-sandbox");
|
||||
options.AddArgument("headless");
|
||||
}
|
||||
|
||||
options.AddArgument($"window-size={InternalWindowWidth}x{InternalWindowHeight}");
|
||||
|
||||
if(InternalDetectDockerEnvironment)
|
||||
{
|
||||
if(File.Exists("/.dockerenv"))
|
||||
{
|
||||
// When running under docker, ports bindings may not work properly
|
||||
// as the current local host may not be detected properly by the web driver
|
||||
// causing errors like this one:
|
||||
//
|
||||
// [SEVERE]: bind() returned an error, errno=99: Cannot assign requested address (99)
|
||||
//
|
||||
// When InternalDetectDockerEnvironment is set, tell the daemon to listen on
|
||||
// all available interfaces
|
||||
Console.WriteLine($"Container mode enabled, adding whitelisted-ips");
|
||||
options.AddArguments("--whitelisted-ips");
|
||||
}
|
||||
}
|
||||
|
||||
foreach(var arg in InternalSeleniumArgument)
|
||||
{
|
||||
options.AddArguments(arg);
|
||||
}
|
||||
|
||||
if(!string.IsNullOrEmpty(browserPath))
|
||||
{
|
||||
options.BinaryLocation = browserPath;
|
||||
}
|
||||
}
|
||||
|
||||
#region Helpers
|
||||
protected string GetEnvironmentVariable(string variableName, string defaultValue)
|
||||
{
|
||||
var value = Environment.GetEnvironmentVariable(variableName);
|
||||
var hasValue = !string.IsNullOrWhiteSpace(value);
|
||||
|
||||
if(hasValue)
|
||||
{
|
||||
Console.WriteLine($"Overriding value with {variableName} = {value}");
|
||||
}
|
||||
|
||||
return hasValue ? value : defaultValue;
|
||||
}
|
||||
|
||||
protected bool GetEnvironmentVariable(string variableName, bool defaultValue)
|
||||
{
|
||||
var value = Environment.GetEnvironmentVariable(variableName);
|
||||
|
||||
var hasValue = bool.TryParse(value, out var varValue);
|
||||
|
||||
if(hasValue)
|
||||
{
|
||||
Console.WriteLine($"Overriding value with {variableName} = {value}");
|
||||
}
|
||||
|
||||
return hasValue ? varValue : defaultValue;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -0,0 +1,231 @@
|
|||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Text.Json;
|
||||
using OpenQA.Selenium.Chrome;
|
||||
using OpenQA.Selenium.Edge;
|
||||
|
||||
namespace Uno.UITest.Selenium
|
||||
{
|
||||
public class SeleniumDriverManager
|
||||
{
|
||||
public static class Chrome
|
||||
{
|
||||
// Chrome driver selection: http://chromedriver.chromium.org/downloads/version-selection
|
||||
|
||||
public static ChromeDriver FromChromePath(string chromePath, ChromeOptions options)
|
||||
=> new ChromeDriver(
|
||||
new SeleniumDriverManager("chromedriver").GetOrDownloadLatestDriverForBin(
|
||||
ChromeFilePath(),
|
||||
GetDriverLatestVersion,
|
||||
GetDriverUri).FullName,
|
||||
options);
|
||||
|
||||
private static string ChromeFilePath()
|
||||
{
|
||||
var chromePath = $@"{Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86)}\Google\Chrome\Application\chrome.exe";
|
||||
// Chrome might be installed in C:\Program Files\Google...
|
||||
// If file doesn't exist, check there.
|
||||
if(!File.Exists(chromePath))
|
||||
{
|
||||
// Using environment variable here since EnvironMent.SpecialFolder.ProgramFiles resolves to the X86
|
||||
// variant depending on the executable architecture. The path variable always evaluates to the correct path though.
|
||||
chromePath = $@"{Environment.GetEnvironmentVariable("ProgramW6432")}\Google\Chrome\Application\chrome.exe";
|
||||
}
|
||||
return chromePath;
|
||||
}
|
||||
|
||||
public static ChromeDriver FromDriverPath(string driverPath, ChromeOptions options)
|
||||
=> new ChromeDriver(driverPath, options);
|
||||
|
||||
private static Uri GetDriverLatestVersion(Version browserVersion) =>
|
||||
browserVersion.Major <= 114 ?
|
||||
new Uri($"https://chromedriver.storage.googleapis.com/LATEST_RELEASE_{browserVersion.Major}") :
|
||||
new Uri("https://googlechromelabs.github.io/chrome-for-testing/known-good-versions-with-downloads.json");
|
||||
|
||||
private static Uri GetDriverUri(Version browserVersion, string driverVersion)
|
||||
{
|
||||
if(browserVersion.Major <= 114)
|
||||
{
|
||||
return new Uri($"https://chromedriver.storage.googleapis.com/{driverVersion}/chromedriver_win32.zip");
|
||||
}
|
||||
else
|
||||
{
|
||||
var driverInfo = JsonSerializer.Deserialize<Models.Root>(driverVersion);
|
||||
return new Uri((from v in driverInfo.Versions
|
||||
let ver = Version.TryParse(v.Version, out var parsedVersion) ? parsedVersion : default
|
||||
where ver.Major == browserVersion.Major &&
|
||||
ver.Minor == browserVersion.Minor &&
|
||||
(v.Downloads?.Chromedriver?.Any() ?? false)
|
||||
orderby ver descending
|
||||
from platform in v.Downloads.Chromedriver
|
||||
where platform.Platform == "win32"
|
||||
select platform.Url).First());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class Edge
|
||||
{
|
||||
// Edge driver selection https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/#downloads
|
||||
// Edge driver documentation https://docs.microsoft.com/en-us/microsoft-edge/webdriver-chromium
|
||||
|
||||
public static EdgeDriver FromEdgePath(string edgePath, EdgeOptions options)
|
||||
{
|
||||
edgePath = edgePath ?? $@"{Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86)}\Microsoft\Edge\Application\msedge.exe";
|
||||
// Edge might be installed in C:\Program Files\Edge...
|
||||
// If file doesn't exist, check there.
|
||||
if(!File.Exists(edgePath))
|
||||
{
|
||||
// Using environment variable here since EnvironMent.SpecialFolder.ProgramFiles resolves to the X86
|
||||
// variant depending on the executable architecture. The path variable always evaluates to the correct path though.
|
||||
edgePath = $@"{Environment.GetEnvironmentVariable("ProgramW6432")}\Microsoft\Edge\Application\msedge.exe";
|
||||
}
|
||||
|
||||
options.BinaryLocation = edgePath;
|
||||
|
||||
var manager = new SeleniumDriverManager("msedgedriver");
|
||||
var driverPath = manager.GetOrDownloadLatestDriverForBin(edgePath, null, /*GetDriverLatestVersion, */GetDriverUri);
|
||||
|
||||
var svc = EdgeDriverService.CreateDefaultService(driverPath.FullName);//.CreateDefaultServiceFromOptions(driverPath.FullName, "msedgedriver.exe", options);
|
||||
svc.EnableVerboseLogging = true;
|
||||
|
||||
var driver = new EdgeDriver(svc, options);
|
||||
|
||||
return driver;
|
||||
}
|
||||
|
||||
public static EdgeDriver FromDriverPath(string driverPath, EdgeOptions options)
|
||||
=> new EdgeDriver(driverPath, options);
|
||||
|
||||
private static Uri GetDriverLatestVersion(Version browserVersion) => new Uri($"https://msedgedriver.azureedge.net/LATEST_RELEASE_{browserVersion.Major}");
|
||||
private static Uri GetDriverUri(Version browserVersion, string driverVersion) => new Uri($"https://msedgedriver.azureedge.net/{driverVersion}/edgedriver_win32.zip");
|
||||
}
|
||||
|
||||
private SeleniumDriverManager(string driverName)
|
||||
{
|
||||
DriverName = driverName;
|
||||
}
|
||||
|
||||
public string DriverName { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the file version of the provided browser path
|
||||
/// </summary>
|
||||
/// <param name="browserPath">Path to the browser executable</param>
|
||||
protected Version GetVersion(string browserPath)
|
||||
{
|
||||
var process = new Process();
|
||||
process.StartInfo.FileName = "wmic.exe";
|
||||
process.StartInfo.Arguments = $@"datafile where name=""{browserPath.Replace("\\", "\\\\")}"" get Version /value";
|
||||
process.StartInfo.UseShellExecute = false;
|
||||
process.StartInfo.RedirectStandardOutput = true;
|
||||
process.StartInfo.RedirectStandardError = true;
|
||||
process.Start();
|
||||
|
||||
var wincOutput = process.StandardOutput.ReadToEnd();
|
||||
var browserRawVersion = wincOutput.Split('=').LastOrDefault()?.Trim();
|
||||
|
||||
if(Version.TryParse(browserRawVersion, out var browserVersion))
|
||||
{
|
||||
return browserVersion;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NotSupportedException($"Unable to determine the browser version. The used path was [{browserPath}], found raw [{browserRawVersion}] parsed [{browserVersion}].");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the target standard install path for the given version of this driver
|
||||
/// </summary>
|
||||
/// <param name="version">The version of the driver</param>
|
||||
protected FileInfo GetDriverInstallPath(Version version)
|
||||
{
|
||||
var driverLocalPath = Path.Combine(Path.GetTempPath(), "Uno.UITests", $"{DriverName}", version.ToString());
|
||||
Directory.CreateDirectory(driverLocalPath);
|
||||
|
||||
return new FileInfo(driverLocalPath + $"\\{DriverName}.exe");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Download the zip package of the driver, and extract the driver executable to the target install path.
|
||||
/// </summary>
|
||||
/// <param name="driverSourceUri">The Uri of the package of the driver to download</param>
|
||||
/// <param name="driverInstallPath">The target install path of the driver</param>
|
||||
protected void Download(Uri driverSourceUri, FileInfo driverInstallPath)
|
||||
{
|
||||
var tempZipFileName = Path.GetTempFileName();
|
||||
try
|
||||
{
|
||||
Console.WriteLine($"Downloading {DriverName} from [{driverSourceUri.OriginalString}]");
|
||||
new WebClient().DownloadFile(driverSourceUri, tempZipFileName);
|
||||
|
||||
using(var zipFile = ZipFile.OpenRead(tempZipFileName))
|
||||
{
|
||||
zipFile.Entries
|
||||
.FirstOrDefault(x => x.Name.EndsWith($"{DriverName}.exe"))?
|
||||
.ExtractToFile(driverInstallPath.FullName, true);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
try
|
||||
{
|
||||
if(File.Exists(tempZipFileName))
|
||||
{
|
||||
File.Delete(tempZipFileName);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{ // Make sure if the file is locked process doesn't crash
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected delegate Uri GetDriverLatestVersion(Version browserVersion);
|
||||
protected delegate Uri GetDriverUri(Version browserVersion, string driverVersion);
|
||||
|
||||
protected DirectoryInfo GetOrDownloadLatestDriverForBin(
|
||||
string binPath,
|
||||
GetDriverLatestVersion getDriverLatestVersion,
|
||||
GetDriverUri getDriverUri)
|
||||
{
|
||||
if(Environment.OSVersion.Platform == PlatformID.Win32NT)
|
||||
{
|
||||
var version = GetVersion(binPath);
|
||||
var driverFile = GetDriverInstallPath(version);
|
||||
|
||||
if(!driverFile.Exists)
|
||||
{
|
||||
string driverVersion;
|
||||
if(getDriverLatestVersion == null)
|
||||
{
|
||||
driverVersion = version.ToString();
|
||||
}
|
||||
else
|
||||
{
|
||||
var driverLatestVersion = getDriverLatestVersion(version);
|
||||
|
||||
Console.WriteLine($"Fetching driver version for {DriverName} [{version}]");
|
||||
driverVersion = new WebClient().DownloadString(driverLatestVersion).Trim();
|
||||
}
|
||||
|
||||
var driverUri = getDriverUri(version, driverVersion);
|
||||
|
||||
Download(driverUri, driverFile);
|
||||
}
|
||||
|
||||
return driverFile.Directory;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NotSupportedException($"Unable to determine the chrome driver location. Use the {SeleniumAppConfigurator.UNO_UITEST_DRIVER_PATH} environment variable.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Selenium.WebDriver" Version="4.2.0" />
|
||||
<PackageReference Include="System.Text.Json" Version="7.0.3" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.28902.138
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.7.34003.232
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Uno.UITest", "uno.uitest\Uno.UITest.csproj", "{C0578553-D584-48C3-9484-1A25DAD66269}"
|
||||
EndProject
|
||||
|
@ -25,14 +25,13 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sample.Wasm", "Sample\Sampl
|
|||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Uno.UITest.Helpers", "Uno.UITest.Helpers\Uno.UITest.Helpers.csproj", "{B233D12F-E9FD-4239-9742-A2F712752000}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{C6491A5A-8CBB-493C-A8EF-EFF6815F7550}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
Directory.Build.props = Directory.Build.props
|
||||
Directory.Build.targets = Directory.Build.targets
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SharedMSBuildProjectFiles) = preSolution
|
||||
Sample\Sample.Shared\Sample.Shared.projitems*{336cc69a-c9d1-48d3-8029-d80d8989403e}*SharedItemsImports = 4
|
||||
Sample\Sample.Shared\Sample.Shared.projitems*{34403e87-8f3e-40c3-8ece-7f3873bcd693}*SharedItemsImports = 4
|
||||
Sample\Sample.Shared\Sample.Shared.projitems*{6279c845-92f8-4333-ab99-3d213163593c}*SharedItemsImports = 13
|
||||
Sample\Sample.Shared\Sample.Shared.projitems*{74eebcc9-f40e-422b-8c39-ca6e674301ae}*SharedItemsImports = 5
|
||||
Sample\Sample.Shared\Sample.Shared.projitems*{dbce58a5-d2d6-4912-abd4-aa7e12519361}*SharedItemsImports = 4
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Ad-Hoc|Any CPU = Ad-Hoc|Any CPU
|
||||
Ad-Hoc|ARM = Ad-Hoc|ARM
|
||||
|
@ -525,4 +524,11 @@ Global
|
|||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {8151C9E9-B16D-46FF-B9AB-8E19B32E1B4F}
|
||||
EndGlobalSection
|
||||
GlobalSection(SharedMSBuildProjectFiles) = preSolution
|
||||
Sample\Sample.Shared\Sample.Shared.projitems*{336cc69a-c9d1-48d3-8029-d80d8989403e}*SharedItemsImports = 4
|
||||
Sample\Sample.Shared\Sample.Shared.projitems*{34403e87-8f3e-40c3-8ece-7f3873bcd693}*SharedItemsImports = 4
|
||||
Sample\Sample.Shared\Sample.Shared.projitems*{6279c845-92f8-4333-ab99-3d213163593c}*SharedItemsImports = 13
|
||||
Sample\Sample.Shared\Sample.Shared.projitems*{74eebcc9-f40e-422b-8c39-ca6e674301ae}*SharedItemsImports = 5
|
||||
Sample\Sample.Shared\Sample.Shared.projitems*{dbce58a5-d2d6-4912-abd4-aa7e12519361}*SharedItemsImports = 4
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
|
Загрузка…
Ссылка в новой задаче