@@ -13,20 +13,176 @@ We use interfaces where is possible, so you can implement your own version of ta
13
13
14
14
We use Dependency Injection to simplify overriding of implementations.
15
15
16
- ### Quick start #todo
16
+ ### Quick start
17
17
18
18
1 . To start work with this package, simply add the nuget dependency Aquality.Selenium.Core to your project.
19
19
20
- 2 . Setup DI container using Startup.cs
20
+ 2 . Setup DI container using Startup.cs.
21
21
22
- 3 . Extend your elements from Element class
23
-
24
- 4 . Extend ElementFactory
25
-
26
- 5 . ???
27
-
28
- 6 . Profit!
22
+ The simpliest way is to create your ApplicationManager class extended from abstract ApplicationManager with the following simple signature:
23
+ ``` csharp
29
24
25
+ public class ApplicationManager : ApplicationManager <ApplicationManager , YourApplication >
26
+ {
27
+ public static IApplication Application => GetApplication (StartApplicationFunction );
28
+
29
+ public static IServiceProvider ServiceProvider => GetServiceProvider (services => Application );
30
+
31
+ private static Func <IServiceProvider , IApplication > StartApplicationFunction => // your implementation here;
32
+ }
33
+ ```
34
+
35
+ Or, if you need to register your own services / rewrite the implementation , you can achieve it this way :
36
+
37
+ ```csharp
38
+
39
+ public class ApplicationManager : ApplicationManager <ApplicationManager , YourApplication >
40
+ {
41
+ public static YourApplication Application => GetApplication (StartApplicationFunction , RegisterServices (StartApplicationFunction ));
42
+
43
+ public static IServiceProvider ServiceProvider => GetServiceProvider (services => Application , RegisterServices (StartApplicationFunction ));
44
+
45
+ private static IServiceCollection RegisterServices (Func <IServiceProvider , YourApplication > applicationSupplier )
46
+ {
47
+ var services = new ServiceCollection ();
48
+ var startup = new Startup ();
49
+ var settingsFile = startup .GetSettings ();
50
+ startup .ConfigureServices (services , applicationSupplier , settingsFile );
51
+ services .AddSingleton <ITimeoutConfiguration >(new CustomTimeoutConfiguration (settingsFile ));
52
+ return services ;
53
+ }
54
+
55
+ private static Func <IServiceProvider , YourApplication > StartApplicationFunction => // your implementation here;
56
+ }
57
+ ```
58
+ 3. That's it! Work with Application via ApplicationManager or via element services.
59
+
60
+ All the services could be resolved from the DI container via ServiceProvider.
61
+
62
+ ```csharp
63
+ ApplicationManager.Application.Driver.FindElement (CalculatorWindow.OneButton).Click ();
64
+ ApplicationManager.ServiceProvider.GetRequiredService<ConditionalWait>().WaitFor (driver =>
65
+ {
66
+ return driver .FindElements(By.XPath("// *")).Count > 0;
67
+ })
68
+ ApplicationManager .ServiceProvider .GetRequiredService <IElementFinder >()
69
+ .FindElement (CalculatorWindow.ResultsLabel, timeout: LittleTimeout)
70
+ ```
71
+
72
+ 4. Extend your elements from Element class :
73
+ ```csharp
74
+ public abstract class WindowElement : Element
75
+ {
76
+ protected WindowElement (By locator , string name , ElementState state ) : base (locator , name , state )
77
+ {
78
+ }
79
+
80
+ protected override ElementActionRetrier ActionRetrier => ApplicationManager .ServiceProvider .GetRequiredService <ElementActionRetrier >();
81
+
82
+ protected override IApplication Application => ApplicationManager .Application ;
83
+
84
+ protected override ConditionalWait ConditionalWait => ApplicationManager .ServiceProvider .GetRequiredService <ConditionalWait >();
85
+
86
+ protected override IElementFactory Factory => ApplicationManager .ServiceProvider .GetRequiredService <IElementFactory >();
87
+
88
+ protected override IElementFinder Finder => ApplicationManager .ServiceProvider .GetRequiredService <IElementFinder >();
89
+
90
+ protected override LocalizationLogger LocalizationLogger => ApplicationManager .ServiceProvider .GetRequiredService <LocalizationLogger >();
91
+ }
92
+ ```
93
+
94
+ ```csharp
95
+ public class Label : WindowElement
96
+ {
97
+ public Label (By locator , string name , ElementState state ) : base (locator , name , state )
98
+ {
99
+ }
100
+
101
+ protected override string ElementType => " Label" ;
102
+ }
103
+ ```
104
+
105
+ 5. Extend ElementFactory to get your own elements:
106
+ ```csharp
107
+ public static class ElementFactoryExtensions
108
+ {
109
+ public static Label GetLabel (this IElementFactory elementFactory , By elementLocator , string elementName )
110
+ {
111
+ return elementFactory .GetCustomElement (GetLabelSupplier (), elementLocator , elementName );
112
+ }
113
+
114
+ private static ElementSupplier <Label > GetLabelSupplier ()
115
+ {
116
+ return (locator , name , state ) => new Label (locator , name , state );
117
+ }
118
+ }
119
+ ```
120
+
121
+ Or create your own ElementFactory! You can extend it from Core's ElementFactory or just implement IElementFactory interface.
122
+ (Don't forget to register it in the DI container at ApplicationManager!).
123
+
124
+ 6. Work with Windows/Pages/Forms according to PageObject pattern.
125
+ 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:
126
+ ```csharp
127
+ /// <summary >
128
+ /// Defines base class for any UI form.
129
+ /// </summary >
130
+ public abstract class Form
131
+ {
132
+ /// <summary >
133
+ /// Constructor with parameters.
134
+ /// </summary >
135
+ /// <param name =" locator" >Unique locator of the form.</param >
136
+ /// <param name =" name" >Name of the form.</param >
137
+ protected Form(By locator, string name)
138
+ {
139
+ Locator = locator;
140
+ Name = name;
141
+ }
142
+
143
+ /// <summary >
144
+ /// Locator of specified form.
145
+ /// </summary >
146
+ public By Locator { get ; }
147
+
148
+ /// <summary >
149
+ /// Name of specified form.
150
+ /// </summary >
151
+ public string Name { get ; }
152
+
153
+ /// <summary >
154
+ /// Instance of logger <see cref =" Logging.Logger" >
155
+ /// </summary >
156
+ /// <value >Logger instance.</value >
157
+ protected Logger Logger => ApplicationManager .ServiceProvider .GetRequiredService <Logger >();
158
+
159
+ /// <summary >
160
+ /// Element factory <see cref =" IElementFactory" >
161
+ /// </summary >
162
+ /// <value >Element factory.</value >
163
+ protected IElementFactory ElementFactory => ApplicationManager .ServiceProvider .GetRequiredService <IElementFactory >();
164
+
165
+ /// <summary >
166
+ /// Return form state for form locator
167
+ /// </summary >
168
+ /// <value >True - form is opened,
169
+ /// False - form is not opened.</value >
170
+ public bool IsDisplayed => FormLabel .State .WaitForDisplayed ();
171
+
172
+ /// <summary >
173
+ /// Gets size of form element defined by its locator.
174
+ /// </summary >
175
+ public Size Size => FormLabel .GetElement ().Size ;
176
+
177
+ private Label FormLabel => ElementFactory .GetLabel (Locator , Name );
178
+ }
179
+
180
+ ```
181
+
182
+ ### F.A.Q.
183
+
184
+ If 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.
185
+ Also feel free to ask any project's collaborator / to create an issue if needed.
30
186
31
187
32
188
### License
0 commit comments