{"id":38600520,"url":"https://github.com/aquality-automation/aquality-selenium-core-dotnet","last_synced_at":"2026-01-17T08:33:13.169Z","repository":{"id":35135385,"uuid":"206557043","full_name":"aquality-automation/aquality-selenium-core-dotnet","owner":"aquality-automation","description":"Repository contains core abstract implementations for children aquality projects like aquality-selenium, aquality-mobile, aquality-winappdriver","archived":false,"fork":false,"pushed_at":"2025-12-02T11:22:40.000Z","size":392,"stargazers_count":7,"open_issues_count":3,"forks_count":3,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-12-05T07:19:59.108Z","etag":null,"topics":["aquality-core","automation","qa","selenium"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/aquality-automation.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2019-09-05T12:21:04.000Z","updated_at":"2025-12-02T10:55:29.000Z","dependencies_parsed_at":"2023-11-30T22:26:04.187Z","dependency_job_id":"b9ad5301-2863-44b3-8dcf-c8c83a84ce04","html_url":"https://github.com/aquality-automation/aquality-selenium-core-dotnet","commit_stats":null,"previous_names":[],"tags_count":70,"template":false,"template_full_name":null,"purl":"pkg:github/aquality-automation/aquality-selenium-core-dotnet","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aquality-automation%2Faquality-selenium-core-dotnet","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aquality-automation%2Faquality-selenium-core-dotnet/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aquality-automation%2Faquality-selenium-core-dotnet/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aquality-automation%2Faquality-selenium-core-dotnet/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aquality-automation","download_url":"https://codeload.github.com/aquality-automation/aquality-selenium-core-dotnet/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aquality-automation%2Faquality-selenium-core-dotnet/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28504364,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-17T06:57:29.758Z","status":"ssl_error","status_checked_at":"2026-01-17T06:56:03.931Z","response_time":85,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["aquality-core","automation","qa","selenium"],"created_at":"2026-01-17T08:33:12.986Z","updated_at":"2026-01-17T08:33:13.099Z","avatar_url":"https://github.com/aquality-automation.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Build Status](https://dev.azure.com/aquality-automation/aquality-automation/_apis/build/status/aquality-automation.aquality-selenium-core-dotnet?branchName=master)](https://dev.azure.com/aquality-automation/aquality-automation/_build/latest?definitionId=3\u0026branchName=master)\n[![Quality Gate](https://sonarcloud.io/api/project_badges/measure?project=aquality-automation_aquality-selenium-core-dotnet\u0026metric=alert_status)](https://sonarcloud.io/dashboard?id=aquality-automation_aquality-selenium-core-dotnet)\n[![NuGet](https://img.shields.io/nuget/v/Aquality.Selenium.Core)](https://www.nuget.org/packages/Aquality.Selenium.Core)\n\n# Aquality Selenium CORE for .NET\n\n### Overview\n\nThis package is a library with core functions simplifying work with Selenium-controlled applications.\n\nYou've got to use this set of methods, related to most common actions performed with elements.\n\nMost of performed methods are logged using NLog, so you can easily see a history of performed actions in your log. We support different logging languages.\n\nWe use interfaces where is possible, so you can implement your own version of target interface with no need to rewrite other classes.\n\nWe use Dependency Injection to simplify overriding of implementations.\n\n### Components of solution\n\n1. Applications component provides classes and interfaces which help us work with application and DI container. [AqualityServices](https://github.com/aquality-automation/aquality-selenium-core-dotnet/blob/master/Aquality.Selenium.Core/src/Aquality.Selenium.Core/Applications/AqualityServices.cs) can get\\set service provider and application. [Startup](https://github.com/aquality-automation/aquality-selenium-core-dotnet/blob/master/Aquality.Selenium.Core/src/Aquality.Selenium.Core/Applications/Startup.cs) is needed to setup DI container.\n\n2. Configurations component provides classes and interfaces which describe most common configurations of project.\n\n3. Elements component describes classes and interfaces which works with UI elements.\n\n4. Solution contains logger and support several languages, Localization and Logging components helps us to implement this.\n\n5. Resources contains localization and project configuration in json files.\n\n6. Utilities.\n\n7. Waitings component contains classes and interfaces which implement some common waitings, for example, wait till condition is satisfied.\n\n### Quick start\n\n1. To start work with this package, simply add the nuget dependency Aquality.Selenium.Core to your project.\n\n2. Setup DI container using Startup.cs. \n\nThe simpliest way is to create your AqualityServices class extended from abstract AqualityServices with the following simple signature:\n```csharp\n\n    public class AqualityServices : AqualityServices\u003cYourApplication\u003e\n    {\n        public new static bool IsApplicationStarted =\u003e IsApplicationStarted();\n\n        public static YourApplication Application =\u003e GetApplication(services =\u003e StartApplication(services));\n\n        public static IServiceProvider ServiceProvider =\u003e GetServiceProvider(services =\u003e Application);\n\n        private static IApplication StartApplication(IServiceProvider services)\n        {\n            your implementation;\n        }\n    }\n```\n\nIf you need to register your own services / rewrite the implementation, you need override [Startup](https://github.com/aquality-automation/aquality-selenium-core-dotnet/blob/master/Aquality.Selenium.Core/src/Aquality.Selenium.Core/Applications/Startup.cs) and implement AqualityServices like in example below:\n\n```csharp\n        public class AqualityServices : AqualityServices\u003cIApplication\u003e\n        {\n            private static ThreadLocal\u003cYourStartup\u003e startup = new ThreadLocal\u003cYourStartup\u003e();\n\n            public new static bool IsApplicationStarted =\u003e IsApplicationStarted();\n            \n            public static YourApplication Application =\u003e GetApplication(StartApplicationFunction, () =\u003e startup.Value.ConfigureServices(new ServiceCollection(), services =\u003e Application));\n\n            public static IServiceProvider ServiceProvider =\u003e GetServiceProvider(services =\u003e Application,\n                () =\u003e startup.Value.ConfigureServices(new ServiceCollection(), services =\u003e Application));\n\n            public static void SetStartup(Startup startup)\n            {\n                if (startup != null)\n                {\n                    AqualityServices.startup.Value = (YourStartup)startup;\n                }\n            }\n\n            private static Func\u003cIServiceProvider, YourApplication\u003e StartApplicationFunction =\u003e (services) =\u003e your implementation;\n        }\n\n        public class YourStartup : Startup\n        {\n            public override IServiceCollection ConfigureServices(IServiceCollection services, Func\u003cIServiceProvider, IApplication\u003e applicationProvider, ISettingsFile settings = null)\n            {\n                var settingsFile = new JsonSettingsFile($\"Resources.settings.{SpecialSettingsFile}.json\", Assembly.GetExecutingAssembly());\n                base.ConfigureServices(services, applicationProvider, settingsFile);\n                //your services like services.AddSingleton\u003cITimeoutConfiguration\u003e(new TestTimeoutConfiguration(settingsFile));\n                return services;\n            }\n        }\n```\n3. That's it! Work with Application via AqualityServices or via element services.\n\nAll the services could be resolved from the DI container via ServiceProvider.\n\n```csharp\n            AqualityServices.Application.Driver.FindElement(CalculatorWindow.OneButton).Click();\n            AqualityServices.ServiceProvider.GetService\u003cIConditionalWait\u003e().WaitFor(driver =\u003e\n            {\n                return driver.FindElements(By.XPath(\"//*\")).Count \u003e 0;\n            })\n            AqualityServices.ServiceProvider.GetService\u003cIElementFinder\u003e()\n                .FindElement(CalculatorWindow.ResultsLabel, timeout: LittleTimeout)\n```\n\n4. Extend your elements from Element class:\n```csharp\n    public abstract class WindowElement : Element\n    {\n        protected WindowElement(By locator, string name, ElementState state) : base(locator, name, state)\n        {\n        }\n\n        protected override IElementActionRetrier ActionRetrier =\u003e AqualityServices.ServiceProvider.GetService\u003cIElementActionRetrier\u003e();\n\n        protected override IApplication Application =\u003e ApplicationManager.Application;\n\n        protected override IConditionalWait ConditionalWait =\u003e AqualityServices.ServiceProvider.GetService\u003cIConditionalWait\u003e();\n\n        protected override IElementFactory Factory =\u003e AqualityServices.ServiceProvider.GetService\u003cIElementFactory\u003e();\n\n        protected override IElementFinder Finder =\u003e AqualityServices.ServiceProvider.GetService\u003cIElementFinder\u003e();\n\n        protected override ILocalizedLogger LocalizedLogger =\u003e AqualityServices.ServiceProvider.GetService\u003cILocalizedLogger\u003e();\n    }\n```\n\n```csharp\n    public class Label : WindowElement\n    {\n        public Label(By locator, string name, ElementState state) : base(locator, name, state)\n        {\n        }\n\n        protected override string ElementType =\u003e \"Label\";\n    }\n```\n\n5. Extend ElementFactory to get your own elements:\n```csharp\n    public static class ElementFactoryExtensions\n    {\n        public static Label GetLabel(this IElementFactory elementFactory, By elementLocator, string elementName)\n        {\n            return elementFactory.GetCustomElement(GetLabelSupplier(), elementLocator, elementName);\n        }\n\n        private static ElementSupplier\u003cLabel\u003e GetLabelSupplier()\n        {\n            return (locator, name, state) =\u003e new Label(locator, name, state);\n        }\n    }\n```\n\nOr create your own ElementFactory! You can extend it from Core's ElementFactory or just implement IElementFactory interface.\n(Don't forget to register it in the DI container at AqualityServices!).\n\n6. Work with Windows/Pages/Forms according to PageObject pattern.\nCreate a base Form class with protected access to IApplication instance and IElementFactory (and any other needed service) via ApplicationManager. Other forms will inherit from this one with the mentioned services available. Take a look at example here:\n```csharp\n    /// \u003csummary\u003e\n    /// Defines base class for any UI form.\n    /// \u003c/summary\u003e\n    public abstract class Form\n    {\n        /// \u003csummary\u003e\n        /// Constructor with parameters.\n        /// \u003c/summary\u003e\n        /// \u003cparam name=\"locator\"\u003eUnique locator of the form.\u003c/param\u003e\n        /// \u003cparam name=\"name\"\u003eName of the form.\u003c/param\u003e\n        protected Form(By locator, string name)\n        {\n            Locator = locator;\n            Name = name;\n        }\n\n        /// \u003csummary\u003e\n        /// Locator of specified form.\n        /// \u003c/summary\u003e\n        public By Locator { get; }\n\n        /// \u003csummary\u003e\n        /// Name of specified form.\n        /// \u003c/summary\u003e\n        public string Name { get; }\n\n        /// \u003csummary\u003e\n        /// Instance of logger \u003csee cref=\"Logging.Logger\"\u003e\n        /// \u003c/summary\u003e\n        /// \u003cvalue\u003eLogger instance.\u003c/value\u003e\n        protected Logger Logger =\u003e AqualityServices.ServiceProvider.GetService\u003cLogger\u003e();\n\n        /// \u003csummary\u003e\n        /// Element factory \u003csee cref=\"IElementFactory\"\u003e\n        /// \u003c/summary\u003e\n        /// \u003cvalue\u003eElement factory.\u003c/value\u003e\n        protected IElementFactory ElementFactory =\u003e AqualityServices.ServiceProvider.GetService\u003cIElementFactory\u003e();\n\n        /// \u003csummary\u003e\n        /// Return form state for form locator\n        /// \u003c/summary\u003e\n        /// \u003cvalue\u003eTrue - form is opened,\n        /// False - form is not opened.\u003c/value\u003e\n        public bool IsDisplayed =\u003e FormLabel.State.WaitForDisplayed();\n\n        /// \u003csummary\u003e\n        /// Gets size of form element defined by its locator.\n        /// \u003c/summary\u003e\n        public Size Size =\u003e FormLabel.GetElement().Size;\n\n        private Label FormLabel =\u003e ElementFactory.GetLabel(Locator, Name);\n    }\n\n```\n\n### F.A.Q.\n\nIf you've got any questions, take a look at Aquality.Selenium.Core.Tests project - probably it already has an implementation of what you're trying to achieve.\nAlso feel free to ask any project's collaborator / to create an issue if needed.\n\n\n### License\nLibrary's source code is made available under the [Apache 2.0 license](https://github.com/aquality-automation/aquality-selenium-core-dotnet/blob/master/LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faquality-automation%2Faquality-selenium-core-dotnet","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faquality-automation%2Faquality-selenium-core-dotnet","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faquality-automation%2Faquality-selenium-core-dotnet/lists"}