Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Browser manager support #16

Merged
merged 12 commits into from
Jun 23, 2024
2 changes: 1 addition & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,4 @@ jobs:
browser: ${{ matrix.browser }}
github-token: ${{ secrets.GITHUB_TOKEN }}
build-configuration: "${{ matrix.environment == 'Production' && 'Release' || 'Debug' }}"
runtime-environment: "${{ matrix.environment }}"
runtime-environment: "${{ matrix.environment }}"
25 changes: 25 additions & 0 deletions src/Core/Riganti.Selenium.Core/Drivers/FastWebBrowserBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.Linq;
using System.Reflection;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.Extensions;
using Riganti.Selenium.Core.Factories;

namespace Riganti.Selenium.Core.Drivers
Expand Down Expand Up @@ -67,7 +68,31 @@ protected virtual void CleanSessionAndLocalStorage()
/// </summary>
protected virtual void DeleteAllCookies()
{

driverInstance.Manage().Cookies.DeleteAllCookies();

// Firefox driver doesn't list all cookies in Manage().Cookies - therefore JS invocation to remove all cookies
// Copied from https://stackoverflow.com/a/33366171
driverInstance.ExecuteJavaScript(
@"
(function () {
var cookies = document.cookie.split(""; "");
for (var c = 0; c < cookies.length; c++) {
var d = window.location.hostname.split(""."");
while (d.length > 0) {
var cookieBase = encodeURIComponent(cookies[c].split("";"")[0].split(""="")[0]) + '=; expires=Thu, 01-Jan-1970 00:00:01 GMT; domain=' + d.join('.') + ' ;path=';
var p = location.pathname.split('/');
document.cookie = cookieBase + '/';
while (p.length > 0) {
document.cookie = cookieBase + p.join('/');
p.pop();
};
d.shift();
}
}
})();
"
);
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,26 +1,28 @@
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using Riganti.Selenium.Core.Factories;
using System.Collections.Generic;
using System.Runtime.CompilerServices;

namespace Riganti.Selenium.Core.Drivers.Implementation
{
public static class ChromeHelpers
{

public static ChromeDriver CreateChromeDriver(LocalWebBrowserFactory factory)
{

var options = new ChromeOptions();
options.AddArgument("test-type");
options.AddArgument("disable-popup-blocking");

options.AddArguments(factory.Capabilities);
options.BrowserVersion = factory.Options.TryGet(nameof(options.BrowserVersion));

if (factory.GetBooleanOption("disableExtensions"))
{
options.AddArgument("--disable-extensions");
}
return new ChromeDriver(options);
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,5 @@ public CoordinatorWebBrowserBase(CoordinatorWebBrowserFactoryBase factory, Conta
{
Lease = lease;
}

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using System.Collections.Generic;

namespace Riganti.Selenium.Core.Drivers.Implementation
{
public static class DictionaryExtensions
{

public static T2 TryGet<T1, T2>(this IDictionary<T1, T2> dic, T1 key)
{
if (dic is not null && dic.TryGetValue(key, out T2 value) && value is T2)
{
return value;
}
return default;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ public static EdgeDriver CreateEdgeDriver(LocalWebBrowserFactory factory)
{
};

options.BrowserVersion = factory.Options.TryGet(nameof(options.BrowserVersion));
return new EdgeDriver(options);
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,74 +1,26 @@
using System;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using Newtonsoft.Json;
using OpenQA.Selenium.Firefox;
using Riganti.Selenium.Core.Factories;

namespace Riganti.Selenium.Core.Drivers.Implementation
{
public static class FirefoxHelpers
{
private static string pathToFirefoxBinary;

private static FirefoxDriverService service;

static FirefoxHelpers()
{
service = FirefoxDriverService.CreateDefaultService();
// service.LogLevel = FirefoxDriverLogLevel.Trace;
}

public static FirefoxDriver CreateFirefoxDriver(LocalWebBrowserFactory factory)
{
factory.LogInfo($"Creating firefox driver from '{pathToFirefoxBinary}'.");

if (!string.IsNullOrWhiteSpace(pathToFirefoxBinary))
{
return CreateAlternativeInstance();
}

try
{
return new FirefoxDriver(service, GetFirefoxOptions());
}
catch (Exception e)
{
factory.LogInfo("Firefox driver could not be created.");
factory.LogError(e);

var env = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles);
if (env.Contains("(x86)"))
{
env = env.Replace("(x86)", "").Trim();
}
var firefox = "Mozilla Firefox\\Firefox.exe";
if (File.Exists(Path.Combine(env, firefox)))
{
return CreateAlternativeInstance(env, firefox);
}

env = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86);
if (File.Exists(Path.Combine(env, firefox)))
{
return CreateAlternativeInstance(env, firefox);
}
throw;
}
}

private static FirefoxDriver CreateAlternativeInstance(string env, string firefox)
{
pathToFirefoxBinary = Path.Combine(env, firefox);
return CreateAlternativeInstance();
}

private static FirefoxDriver CreateAlternativeInstance()
{
var firefoxOptions = new FirefoxOptions()
{
BrowserExecutableLocation = pathToFirefoxBinary,
Profile = GetFirefoxProfile()
};
return new FirefoxDriver(firefoxOptions);
var ffOptions = GetFirefoxOptions(factory.Options);
var driver = new FirefoxDriver(service, ffOptions);
return driver;
}

public static FirefoxProfile GetFirefoxProfile()
Expand All @@ -80,9 +32,13 @@ public static FirefoxProfile GetFirefoxProfile()
return profile;
}

public static FirefoxOptions GetFirefoxOptions()
public static FirefoxOptions GetFirefoxOptions(System.Collections.Generic.IDictionary<string, string> _options)
{
var options = new FirefoxOptions { Profile = GetFirefoxProfile() };
var options = new FirefoxOptions
{
Profile = GetFirefoxProfile()
};
options.BrowserVersion = _options.TryGet(nameof(options.BrowserVersion));
return options;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,8 @@ public static InternetExplorerDriver CreateInternetExplorerDriver(LocalWebBrowse
{
BrowserCommandLineArguments = "-private"
};

options.BrowserVersion = factory.Options.TryGet(nameof(options.BrowserVersion));
return new InternetExplorerDriver(options);
}

}
}
2 changes: 1 addition & 1 deletion src/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<Authors>RIGANTI</Authors>
<Description>Basic utilities for performing UI tests based on selenium on CI servers.</Description>
<PackageTags>selenium;ui;tests;riganti;ci</PackageTags>
<Version>3.0.0-preview15-final</Version>
<Version>3.0.0-preview17-browser-manager</Version>
<PackageIcon>Icon.png</PackageIcon>
<RepositoryType>git</RepositoryType>
<RepositoryUrl>https://github.com/riganti/selenium-utils</RepositoryUrl>
Expand Down
26 changes: 0 additions & 26 deletions src/Integrations/Riganti.Selenium.xUnit/XunitTestSuiteRunner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,30 +23,4 @@ public override void RunInAllBrowsers(ISeleniumTest testClass, Action<IBrowserWr
base.RunInAllBrowsers(testClass, action, callerMemberName, callerFilePath, callerLineNumber);
}
}

//public class SeleniumInternalXunitRunnerReporter : Xunit.IRunnerReporter
//{
// public string Description => "This reporter is a bit hack to close all resources when test execution ends.";

// public bool IsEnvironmentallyEnabled => true;

// public string RunnerSwitch => "riganti-selenium";

// public IMessageSink CreateMessageHandler(IRunnerLogger logger)
// {
// return new SeleniumMessageSink();
// }
//}
//public class SeleniumMessageSink : IMessageSink
//{
// public bool OnMessage(IMessageSinkMessage message)
// {
// if (message is TestAssemblyExecutionFinished)
// {
// if (Debugger.IsAttached)
// Debugger.Break();
// }
// return true;
// }
//}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<Content Include="**/*.dothtml;**/*.dotmaster;**/*.dotcontrol" Exclude="obj/**/*.*;bin/**/*.*" CopyToPublishDirectory="Always" />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
{
"factories": {
"chrome:fast": {
"capabilities": [ "--window-size=1920,1080" ]//, "--headless", "--disable-gpu" ]
"capabilities": [ "--window-size=1920,1080", "--headless", "--disable-gpu" ],
"Options": {
"BrowserVersion": "124"
}
}
//"firefox:dev": {
//}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,15 +70,24 @@ public void SelectMethod_XPathToRoot_ExpectedException()
}

[TestMethod]
[ExpectedSeleniumException(typeof(InvalidSelectorException))]
public void SelectMethod_InvalidXPathSelector_ExpectedException()
{
this.RunInAllBrowsers(browser =>
try
{
browser.NavigateToUrl("/test/ClickTest");
var elem = browser.Single("#span");
elem.Single("///***-*///@@##@šš+š++++---><<>''", By.XPath);
});
this.RunInAllBrowsers(browser =>
{
browser.NavigateToUrl("/test/ClickTest");
var elem = browser.Single("#span");
elem.Single("///***-*///@@##@šš+š++++---><<>''", By.XPath);
});
}
catch (System.Exception)
{
// ignore
// reason: Firefox driver and Chrome driver throw different exceptions
return;
}
throw new System.Exception("SelectMethod_InvalidXPathSelector_ExpectedException was supposed to fail!!!");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ public void CookieTest()
browser.NavigateToUrl("/test/Cookies");
browser.First("#CookieIndicator").CheckIfInnerTextEquals("default value");

browser.Click("#SetCookies").Wait();
browser.Click("#SetCookies").Wait(1000);
browser.NavigateToUrl("/test/Cookies");
browser.First("#CookieIndicator").CheckIfInnerTextEquals("new value");
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
{
"factories": {
"chrome:fast": {
"capabilities": [ "--no-sandbox" ]
"capabilities": [ "--no-sandbox" ],
"Options": {
"BrowserVersion": "124"
}
}
},
"baseUrls": [
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Newtonsoft.Json;
using OpenQA.Selenium;

[TestClass]
public class SeleniumManagerTests
{
[TestMethod]
public void GetBinariesVersion113()
{
var data1 = SeleniumManager.BinaryPaths("--browser firefox --driver geckodriver --browser-version 113");
Console.WriteLine("Firefox binaries: " + JsonConvert.SerializeObject(data1));
Assert.IsNotNull(data1["browser_path"]);
Assert.IsNotNull(data1["driver_path"]);

var data2 = SeleniumManager.BinaryPaths("--browser chrome --driver chromedriver --browser-version 113");
Console.WriteLine("Chrome binaries: " + JsonConvert.SerializeObject(data2));
Assert.IsNotNull(data2["browser_path"]);
Assert.IsNotNull(data2["driver_path"]);
}

[TestMethod]
public void GetBinariesVersionStable()
{
var data1 = SeleniumManager.BinaryPaths("--browser firefox --driver geckodriver --browser-version stable");
Console.WriteLine("Firefox binaries: " + JsonConvert.SerializeObject(data1));
Assert.IsNotNull(data1["browser_path"]);
Assert.IsNotNull(data1["driver_path"]);

var data2 = SeleniumManager.BinaryPaths("--browser chrome --driver chromedriver --browser-version stable");
Console.WriteLine("Chrome binaries: " + JsonConvert.SerializeObject(data2));
Assert.IsNotNull(data2["browser_path"]);
Assert.IsNotNull(data2["driver_path"]);
}
}
12 changes: 10 additions & 2 deletions src/Tests/Riganti.Selenium.Core.Samples.Tests/seleniumconfig.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
{
"factories": {
"chrome:fast": {
"capabilities": [ "--window-size=1920,1080", "--headless", "--disable-gpu" ]
}
"capabilities": [ "--window-size=1920,1080", "--headless", "--disable-gpu" ],
"Options": {
"BrowserVersion": "124"
}
},
//"firefox:fast": {
// "Options": {
// "BrowserVersion": "104"
// }
//}
//"chrome:coordinator": {
// "options": {
// "coordinatorUrl": "http://localhost:62242/"
Expand Down
Loading
Loading