Skip to content

Commit 1de81b9

Browse files
knyshmialeska
authored andcommitted
Update README.md (#56)
* Update README.md
1 parent 6905230 commit 1de81b9

File tree

1 file changed

+65
-31
lines changed

1 file changed

+65
-31
lines changed

README.md

Lines changed: 65 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -16,59 +16,93 @@ We use interfaces where is possible, so you can implement your own version of ta
1616

1717
We use Dependency Injection to simplify overriding of implementations.
1818

19+
### Components of solution
20+
21+
1. 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.
22+
23+
2. Configurations component provides classes and interfaces which describe most common configurations of project.
24+
25+
3. Elements component describes classes and interfaces which works with UI elements.
26+
27+
4. Solution contains logger and support several languages, Localization and Logging components helps us to implement this.
28+
29+
5. Resources contains localization and project configuration in json files.
30+
31+
6. Utilities.
32+
33+
7. Waitings component contains classes and interfaces which implement some common waitings, for example, wait till condition is satisfied.
34+
1935
### Quick start
2036

2137
1. To start work with this package, simply add the nuget dependency Aquality.Selenium.Core to your project.
2238

2339
2. Setup DI container using Startup.cs.
2440

25-
The simpliest way is to create your ApplicationManager class extended from abstract ApplicationManager with the following simple signature:
41+
The simpliest way is to create your AqualityServices class extended from abstract AqualityServices with the following simple signature:
2642
```csharp
2743

28-
public class ApplicationManager : ApplicationManager<ApplicationManager, YourApplication>
29-
{
30-
public static IApplication Application => GetApplication(StartApplicationFunction);
44+
public class AqualityServices : AqualityServices<YourApplication>
45+
{
46+
public new static bool IsApplicationStarted => IsApplicationStarted();
47+
48+
public static YourApplication Application => GetApplication(services => StartApplication(services));
3149

32-
public static IServiceProvider ServiceProvider => GetServiceProvider(services => Application);
50+
public static IServiceProvider ServiceProvider => GetServiceProvider(services => Application);
3351

34-
private static Func<IServiceProvider, IApplication> StartApplicationFunction => // your implementation here;
52+
private static IApplication StartApplication(IServiceProvider services)
53+
{
54+
your implementation;
3555
}
56+
}
3657
```
3758

38-
Or, if you need to register your own services / rewrite the implementation, you can achieve it this way:
59+
If 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:
3960

4061
```csharp
41-
42-
public class ApplicationManager : ApplicationManager<ApplicationManager, YourApplication>
62+
public class AqualityServices : AqualityServices<IApplication>
4363
{
44-
public static YourApplication Application => GetApplication(StartApplicationFunction, () => RegisterServices(services => Application));
64+
private static ThreadLocal<YourStartup> startup = new ThreadLocal<YourStartup>();
4565

46-
public static IServiceProvider ServiceProvider => GetServiceProvider(services => Application, () => RegisterServices(services => Application));
66+
public new static bool IsApplicationStarted => IsApplicationStarted();
67+
68+
public static YourApplication Application => GetApplication(StartApplicationFunction, () => startup.Value.ConfigureServices(new ServiceCollection(), services => Application));
4769

48-
private static IServiceCollection RegisterServices(Func<IServiceProvider, YourApplication> applicationSupplier)
70+
public static IServiceProvider ServiceProvider => GetServiceProvider(services => Application,
71+
() => startup.Value.ConfigureServices(new ServiceCollection(), services => Application));
72+
73+
public static void SetStartup(Startup startup)
4974
{
50-
var services = new ServiceCollection();
51-
var startup = new Startup();
52-
var settingsFile = startup.GetSettings();
53-
startup.ConfigureServices(services, applicationSupplier, settingsFile);
54-
services.AddSingleton<ITimeoutConfiguration>(new CustomTimeoutConfiguration(settingsFile));
55-
return services;
75+
if (startup != null)
76+
{
77+
AqualityServices.startup.Value = (YourStartup)startup;
78+
}
5679
}
5780

58-
private static Func<IServiceProvider, YourApplication> StartApplicationFunction => // your implementation here;
81+
private static Func<IServiceProvider, YourApplication> StartApplicationFunction => (services) => your implementation;
82+
}
83+
84+
public class YourStartup : Startup
85+
{
86+
public override IServiceCollection ConfigureServices(IServiceCollection services, Func<IServiceProvider, IApplication> applicationProvider, ISettingsFile settings = null)
87+
{
88+
var settingsFile = new JsonSettingsFile($"Resources.settings.{SpecialSettingsFile}.json", Assembly.GetExecutingAssembly());
89+
base.ConfigureServices(services, applicationProvider, settingsFile);
90+
//your services like services.AddSingleton<ITimeoutConfiguration>(new TestTimeoutConfiguration(settingsFile));
91+
return services;
92+
}
5993
}
6094
```
61-
3. That's it! Work with Application via ApplicationManager or via element services.
95+
3. That's it! Work with Application via AqualityServices or via element services.
6296

6397
All the services could be resolved from the DI container via ServiceProvider.
6498

6599
```csharp
66-
ApplicationManager.Application.Driver.FindElement(CalculatorWindow.OneButton).Click();
67-
ApplicationManager.ServiceProvider.GetRequiredService<ConditionalWait>().WaitFor(driver =>
100+
AqualityServices.Application.Driver.FindElement(CalculatorWindow.OneButton).Click();
101+
AqualityServices.ServiceProvider.GetService<IConditionalWait>().WaitFor(driver =>
68102
{
69103
return driver.FindElements(By.XPath("//*")).Count > 0;
70104
})
71-
ApplicationManager.ServiceProvider.GetRequiredService<IElementFinder>()
105+
AqualityServices.ServiceProvider.GetService<IElementFinder>()
72106
.FindElement(CalculatorWindow.ResultsLabel, timeout: LittleTimeout)
73107
```
74108

@@ -80,17 +114,17 @@ All the services could be resolved from the DI container via ServiceProvider.
80114
{
81115
}
82116

83-
protected override ElementActionRetrier ActionRetrier => ApplicationManager.ServiceProvider.GetRequiredService<ElementActionRetrier>();
117+
protected override IElementActionRetrier ActionRetrier => AqualityServices.ServiceProvider.GetService<IElementActionRetrier>();
84118

85119
protected override IApplication Application => ApplicationManager.Application;
86120

87-
protected override ConditionalWait ConditionalWait => ApplicationManager.ServiceProvider.GetRequiredService<ConditionalWait>();
121+
protected override IConditionalWait ConditionalWait => AqualityServices.ServiceProvider.GetService<IConditionalWait>();
88122

89-
protected override IElementFactory Factory => ApplicationManager.ServiceProvider.GetRequiredService<IElementFactory>();
123+
protected override IElementFactory Factory => AqualityServices.ServiceProvider.GetService<IElementFactory>();
90124

91-
protected override IElementFinder Finder => ApplicationManager.ServiceProvider.GetRequiredService<IElementFinder>();
125+
protected override IElementFinder Finder => AqualityServices.ServiceProvider.GetService<IElementFinder>();
92126

93-
protected override LocalizationLogger LocalizationLogger => ApplicationManager.ServiceProvider.GetRequiredService<LocalizationLogger>();
127+
protected override ILocalizedLogger LocalizedLogger => AqualityServices.ServiceProvider.GetService<ILocalizedLogger>();
94128
}
95129
```
96130

@@ -122,7 +156,7 @@ All the services could be resolved from the DI container via ServiceProvider.
122156
```
123157

124158
Or create your own ElementFactory! You can extend it from Core's ElementFactory or just implement IElementFactory interface.
125-
(Don't forget to register it in the DI container at ApplicationManager!).
159+
(Don't forget to register it in the DI container at AqualityServices!).
126160

127161
6. Work with Windows/Pages/Forms according to PageObject pattern.
128162
Create 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:
@@ -157,13 +191,13 @@ Create a base Form class with protected access to IApplication instance and IEle
157191
/// Instance of logger <see cref="Logging.Logger">
158192
/// </summary>
159193
/// <value>Logger instance.</value>
160-
protected Logger Logger => ApplicationManager.ServiceProvider.GetRequiredService<Logger>();
194+
protected Logger Logger => AqualityServices.ServiceProvider.GetService<Logger>();
161195

162196
/// <summary>
163197
/// Element factory <see cref="IElementFactory">
164198
/// </summary>
165199
/// <value>Element factory.</value>
166-
protected IElementFactory ElementFactory => ApplicationManager.ServiceProvider.GetRequiredService<IElementFactory>();
200+
protected IElementFactory ElementFactory => AqualityServices.ServiceProvider.GetService<IElementFactory>();
167201

168202
/// <summary>
169203
/// Return form state for form locator

0 commit comments

Comments
 (0)