Skip to content

Feature new selenium project #153

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

Open
wants to merge 33 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
1abb777
Added first code to test poc
Oleg-Mozhey Apr 13, 2024
8c7d441
small adjustment
Oleg-Mozhey Apr 13, 2024
7372179
first selenium case
Oleg-Mozhey Apr 13, 2024
20899fd
reference added
Oleg-Mozhey Apr 13, 2024
b367a4a
changed test case
Oleg-Mozhey Apr 13, 2024
b952d3d
small changes
Oleg-Mozhey Apr 13, 2024
7e07887
changed project path
Oleg-Mozhey Apr 13, 2024
1ad0028
project structure change
Oleg-Mozhey Apr 13, 2024
47c1f81
structure
Oleg-Mozhey Apr 13, 2024
d30a9c4
simplify dependepcies
Oleg-Mozhey Apr 13, 2024
747ed1c
small changes
Oleg-Mozhey Apr 13, 2024
8d19410
versions update
Oleg-Mozhey Apr 13, 2024
ae29a6d
fix config project reference
Oleg-Mozhey Apr 13, 2024
0cd2f58
use the same version for different projects
Oleg-Mozhey Apr 13, 2024
7dcd2b2
Added configuration
Oleg-Mozhey Apr 13, 2024
e776d6f
fixed config
Oleg-Mozhey Apr 13, 2024
ff12659
Some initial configuration without specific purpose
Oleg-Mozhey Apr 13, 2024
fa93ac5
Added configs to selenium project
Oleg-Mozhey Apr 13, 2024
39c4c0d
import selenium web driver to selenium project
Oleg-Mozhey Apr 13, 2024
0546bc1
small changes
Oleg-Mozhey Apr 13, 2024
92427f5
Added hooks
Oleg-Mozhey Apr 13, 2024
cea0a07
Added first poc
Oleg-Mozhey Apr 13, 2024
a030c6a
changed version
Oleg-Mozhey Apr 13, 2024
38591a5
update configs
Oleg-Mozhey Apr 13, 2024
dd645c5
added dependencies
Oleg-Mozhey Apr 13, 2024
18f2aa2
Added first code to switch application page
Oleg-Mozhey Apr 13, 2024
fd84df1
small changes to bring button binding
Oleg-Mozhey Apr 14, 2024
3b9d6d5
added first configuration of web elements
Oleg-Mozhey Apr 14, 2024
17b4a47
Added basis for interacting with web elements
Oleg-Mozhey Apr 14, 2024
4a04744
moved implementation to SeleniumWebElement
Oleg-Mozhey Apr 14, 2024
ebea0ef
added poc for finnd element
Oleg-Mozhey Apr 14, 2024
b3b120a
Finished poc for selenium interraction
Oleg-Mozhey Apr 14, 2024
85df25e
Merge remote-tracking branch 'origin/main' into feature_new_selenium_…
Oleg-Mozhey Apr 18, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<RootNamespace>Behavioral.Automation.Implementation.Selenium</RootNamespace>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0" />
<PackageReference Include="Selenium.Support" Version="4.19.0" />
<PackageReference Include="Selenium.WebDriver" Version="4.19.0" />
<PackageReference Include="SpecFlow.NUnit" Version="3.9.74" />
<PackageReference Include="nunit" Version="3.13.2" />
<PackageReference Include="NUnit3TestAdapter" Version="4.1.0" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\Behavioral.Automation.AsyncAbstractions.UI\Behavioral.Automation.AsyncAbstractions.UI.csproj" />
<ProjectReference Include="..\..\Behavioral.Automation.Configs\Behavioral.Automation.Configs.csproj" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
using System.Diagnostics.CodeAnalysis;
using Behavioral.Automation.Configs;
using Behavioral.Automation.Implementation.Selenium.Configs;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace Behavioral.Automation.Implementation.Selenium.Bindings;

public class BrowserRunner
{
public IWebDriver Driver;

/// <summary>
/// Driver initialization
/// </summary>
/// <param name="driver">IWebDriver object</param>
public void OpenBrowser([NotNull] IWebDriver driver)
{
Driver = driver;
}


/// <summary>
/// Driver disposal
/// </summary>
public void CloseBrowser()
{
Driver.Dispose();
}

/// <summary>
/// Open and configure Google Chrome browser
/// </summary>
/// <param name="options">Browser parameters</param>
public void OpenChrome(ChromeOptions options = null)
{
// new DriverManager().SetUpDriver(new ChromeConfig(), VersionResolveStrategy.MatchingBrowser);

var downloadPath = ConfigManager.GetConfig<Config>().DownloadPath ?? Environment.CurrentDirectory;

if (options == null)
{
options = new ChromeOptions();
options.AddArguments(new List<string>(
ConfigManager.GetConfig<Config>().BrowserParameters.Split(" ", StringSplitOptions.RemoveEmptyEntries)));
if (ConfigManager.GetConfig<Config>().BrowserParameters.Contains("headless"))
{
ConfigureChromeHeadlessDownload(options, downloadPath);
}

if (ConfigManager.GetConfig<Config>().AccessClipboard)
{
ConfigureClipboardAccess(options);
}

options.AddUserProfilePreference("intl.accept_languages", "en,en_US");
options.AcceptInsecureCertificates = ConfigManager.GetConfig<Config>().AcceptInsecureCertificates;
options.SetLoggingPreference(LogType.Browser, LogLevel.All);
if (!string.IsNullOrWhiteSpace(ConfigManager.GetConfig<Config>().BrowserBinaryLocation))
{
options.BinaryLocation =
Environment.ExpandEnvironmentVariables(ConfigManager.GetConfig<Config>().BrowserBinaryLocation);
}

if (!string.IsNullOrWhiteSpace(ConfigManager.GetConfig<Config>().UnhandledPromptBehavior))
{
options.UnhandledPromptBehavior = ConfigManager.GetConfig<Config>().UnhandledPromptBehavior switch
{
"Accept" => UnhandledPromptBehavior.Accept,
"Dismiss" => UnhandledPromptBehavior.Dismiss,
"Ignore" => UnhandledPromptBehavior.Ignore,
_ => options.UnhandledPromptBehavior
};
}
}

var driver = new ChromeDriver(options);
var param = new Dictionary<string, object>
{
{"behavior", "allow"},
{"downloadPath", downloadPath}
};
driver.ExecuteCdpCommand("Page.setDownloadBehavior", param);
OpenBrowser(driver);
}

/// <summary>
/// Configure Google Chrome downloads to work correctly in headless mode
/// </summary>
/// <param name="options">Chrome configuration parameters</param>
/// <param name="downloadPath">Directory to download files to</param>
private void ConfigureChromeHeadlessDownload(ChromeOptions options, string downloadPath)
{
options.AddUserProfilePreference("download.prompt_for_download", "false");
options.AddUserProfilePreference("download.directory_upgrade", "true");
options.AddUserProfilePreference("download.default_directory", downloadPath);
}

private void ConfigureClipboardAccess(ChromeOptions options)
{
var clipboardExceptionSettings = new Dictionary<string, object>
{
{
ConfigManager.GetConfig<Config>().BaseUrl,
new Dictionary<string, long>
{
{"last_modified", DateTimeOffset.Now.ToUnixTimeMilliseconds()},
{"setting", 1}
}
}
};
options.AddUserProfilePreference("profile.content_settings.exceptions.clipboard", clipboardExceptionSettings);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
using System.Diagnostics;
using System.Net;
using Behavioral.Automation.AsyncAbstractions.UI.BasicImplementations;
using Behavioral.Automation.AsyncAbstractions.UI.Interfaces;
using Behavioral.Automation.Configs;
using Behavioral.Automation.Implementation.Selenium.Configs;
using BoDi;
using NUnit.Framework;
using TechTalk.SpecFlow;

namespace Behavioral.Automation.Implementation.Selenium.Bindings;

[Binding]
public class Hooks
{
private readonly IObjectContainer _objectContainer;
private readonly ITestRunner _runner;
private readonly BrowserRunner _browserRunner;
private static Process _coreRunProcess;
private readonly WebContext _webContext;

public Hooks(IObjectContainer objectContainer, ITestRunner runner, BrowserRunner browserRunner, WebContext webContext)
{
_objectContainer = objectContainer;
_runner = runner;
_browserRunner = browserRunner;
_webContext = webContext;
}

private static bool IsConnectionEstablished()
{
try
{
WebRequest.CreateHttp(ConfigManager.GetConfig<Config>().BaseUrl).GetResponse();
return true;
}
catch (WebException)
{
return false;
}
}

private static void RunTestApp()
{
string testAppPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "..", "..", "..", "..", "..", "src",
"BlazorApp");

_coreRunProcess = new Process
{
StartInfo = new ProcessStartInfo
{
FileName = "cmd.exe",
Arguments = "/c dotnet run",
WorkingDirectory = testAppPath
}
};
_coreRunProcess.Start();
}

[BeforeTestRun]
public static void StartDemoApp()
{
if (!IsConnectionEstablished())
RunTestApp();
}

[AfterTestRun]
public static void StopDemoApp()
{
if (_coreRunProcess != null)
{
_coreRunProcess.Kill(true);
_coreRunProcess.Dispose();
}
}

[AfterScenario]
public void CloseBrowser()
{
_browserRunner.CloseBrowser();
}

[BeforeScenario(Order = 0)]
public void Bootstrap()
{
//Assert.SetRunner(_runner);
//_objectContainer.RegisterTypeAs<UserInterfaceBuilder, IUserInterfaceBuilder>();
//_servicesBuilder.Build();

_browserRunner.OpenChrome();
_webContext.Page = new Page();
((Page) _webContext.Page).driver = _browserRunner.Driver;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using Behavioral.Automation.AsyncAbstractions.UI.Interfaces;
using Behavioral.Automation.Configs;
using Behavioral.Automation.Implementation.Selenium.Configs;
using OpenQA.Selenium;

namespace Behavioral.Automation.Implementation.Selenium.Bindings;

public class Page : IPage
{
public IWebDriver driver;
public Task GoToUrlAsync(string url)
{
return Task.Run(() => { driver.Navigate().GoToUrl(url); });
}

public Task GoToApplicationUrlAsync()
{
return Task.Run(() => { driver.Navigate().GoToUrl(ConfigManager.GetConfig<Config>().BaseUrl); });
}

public Task HaveTitleAsync(string title)
{
throw new NotImplementedException();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using Microsoft.Extensions.Configuration;

namespace Behavioral.Automation.Implementation.Selenium.Configs;

public class Config
{
[ConfigurationKeyName("BASE_URL")] public string BaseUrl { get; set; }

[ConfigurationKeyName("BROWSER_PARAMS")]
public string BrowserParameters { get; set; }

[ConfigurationKeyName("DOWNLOAD_PATH")]
public string DownloadPath { get; set; } = AppContext.BaseDirectory;

[ConfigurationKeyName("ACCEPT_INSECURE_CERTIFICATES")]
public bool AcceptInsecureCertificates { get; set; } = true;

[ConfigurationKeyName("SEARCH_ATTRIBUTE")]
public string SearchAttribute { get; set; }

[ConfigurationKeyName("ACCESS_CLIPBOARD")]
public bool AccessClipboard { get; set; } = false;

[ConfigurationKeyName("BROWSER_BINARY_LOCATION")]
public string BrowserBinaryLocation { get; set; }

[ConfigurationKeyName("UNHANDLED_PROMPT_BEHAVIOR")]
public string UnhandledPromptBehavior { get; set; }

[ConfigurationKeyName("ASSERT_ATTEMPTS")]
public int? AssertAttempts { get; set; } = 30;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace Behavioral.Automation.Playwright.Pages;

public interface ISelectorStorage
{

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using Behavioral.Automation.AsyncAbstractions.UI.BasicImplementations;
using Behavioral.Automation.Configs;
using Behavioral.Automation.Implementation.Selenium.Configs;
using Behavioral.Automation.Implementation.Selenium.Selectors;
using Behavioral.Automation.Playwright.Pages;

namespace Behavioral.Automation.Implementation.Selenium.Pages;

class MainPageExample : ISelectorStorage
{
private static readonly string Id = ConfigManager.GetConfig<Config>().SearchAttribute;

public ElementSelector DemoLabel = new() {IdSelector = "label-simple-text"};
public ButtonSelector IncrementCountButton = new() {XpathSelector = "//button[@data-automation-id='increment-count-button']"};

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using Behavioral.Automation.AsyncAbstractions.UI.BasicImplementations;

namespace Behavioral.Automation.Implementation.Selenium.Selectors;

public class ButtonSelector : ElementSelector
{

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using System.Runtime.ConstrainedExecution;
using Behavioral.Automation.AsyncAbstractions.UI.Interfaces;
using BoDi;
using TechTalk.SpecFlow;

namespace Behavioral.Automation.Implementation.Selenium.Services;

[Binding]
public class Hooks
{
private readonly ObjectContainer _objectContainer;

public Hooks(ObjectContainer objectContainer)
{
_objectContainer = objectContainer;
}

// Configuration of DI and Factories should be done with order 0
[BeforeScenario(Order = 0)]
public void ConfigureUiImplementations()
{
_objectContainer.RegisterTypeAs<WebElementStorageService, IWebElementStorageService>();
}
}
Loading