HtmlElement.Net
|
HtmlElements is .NET library complementing to Selenium WebDriver page object model by allowing you to create more complex and sophysticated page objects. It also provides set of standard page objects for commonly used HTML elements (links, input fields, images, frames, etc), alternative wait syntax, smart frames and some other usefull utilities. You can add it to your project by installing HtmlElements nuget package. More information can be found in API reference.
The main goal of HtmlElements library is to represent any given page or part of a page as set of smaller reusable components. Every component is a class having any number of nested components and public methods. Smaller components create a hierarchy similar to DOM with a page component at the top.
Assuming we would like to model a page listing nuget packages (https://www.nuget.org/packages) we could describe every package from list as a separate component and then have list of such components inside page object describing page as a whole.
PageObjectFactory is creating and initializing page objects. It is one of the core library components since it creates and recursively initializes all page objects in a given hierarchy. Page factory can initialize fields and properties which type is derived from IWebElement or IList<IWebElement>. It can create (and initialize) page object of any type using default or custom constructor. It also provides few extension points.
Default page factory implementation wraps raw WebElements located in browser into proxy loading elements on demand and handling StaleElementReferenceException by reloading the underlying element. It is possible to change how proxy is being created by implementing IProxyFactory interface and how elements are loaded by implementing ILoaderFactory interface. Also it is possible to change the way how new page objects are being instantiated by overriding CreatePageObjectInstance default factory method and how page object members are being initialized by overriding CreateMemberInstance method.
Please refer to API reference for more details.
Whenever a web component is used among multiple pages/components and WebDriver can find it with same element locator it's locator can be defined next to a component class using ElementLocator
attribute. It can later be overriden with FindsBy
attribute.
When neither of ElementLocator
or FindsBy
attributes are available for given field or property it will point to an element having id
attribute equal to field or property name.
In addition to creating your custom page objects you can use set predefined components which models commonly used DOM elements. Following components can be found in HtmlElements.Elements namespace:
All of the above components are derived from HtmlElement which is also a good candidate to derive custom components from.
While writing selenium tests you'll often found your self waiting until something happens in browser. It could be slow loading page, dialog which takes few seconds to show up or hide, background process which must finish until test can proceed. The simple way is to stop thread for few seconds. Reliable way is to use WebDriverWait or DefaultWait classes being part of selenium webdriver library. The convenient way is to use extension methods provided by current library. Just take a look on few examples below.
So basically you need to say what are you waiting for ? For how long ? How often to check weather it happened ? What message should timeout exception be thrown with ?
Sometimes tests need to interact with HTML frames. In order to do it we need to switch wedriver context to specific frame firts and switch it back after we've done. It is exactly what FrameContextOverride class is desgined to do.
HtmlFrame is another class which makes life easier when it comes to working with frames. When created by default page object factory (described above) it's wrapped search context is set to WebDriver instance instead of WebElement as it is done for other custom elements. It allows using it as a base class for custom frame page objects. Previous example could be rewritten as shown below.
There might be cases when you might want to change default implicit wait WebDriver option for specific operation and restore it back after it is done. For example you might set to 30 seconds for most cases but do not want to wait for element which you expect to be removed from DOM. You could use ImplicitWaitOverride for it's purpose.
Often people writing selenium tests want to check weather some element or another exist on a page. There are two possible way of doing so: expose raw WebElements or create IsXXXDisplayed properties. Author deslike both and the idea itself. Newertheless people still need to do it. Element group is attempt to make it in a way which does not break encapsulation. How it works: