Contributions to the Headless Chrome .NET API ๐๐งช โ๏ธ PuppeteerSharp.Contrib.PageObjects is a library for writing browser tests using the page object pattern with the Puppeteer Sharp API. โ๏ธ It provides a convenient way to write readable and robust browser tests in .NET ๐ https://hlaueriksson.me/PuppeteerSharp.Contrib.PageObjects/
$ dotnet add package PuppeteerSharp.Contrib.PageObjectsPuppeteerSharp.Contrib.PageObjects is a library for writing browser tests using the page object pattern with the Puppeteer Sharp API.
IPageIElementHandleA page object wraps an PuppeteerSharp.IPage and should encapsulate the way tests interact with a web page.
Create page objects by inheriting PageObject and declare properties decorated with [Selector] attributes.
public class GitHubStartPage : PageObject
{
[Selector("main h1")]
public virtual Task<IElementHandle> Heading { get; }
[Selector("header")]
public virtual Task<GitHubHeader> Header { get; }
public async Task<GitHubSearchPage> SearchAsync(string text)
{
var task = Page.WaitForNavigationAsync<GitHubSearchPage>();
await (await Header).SearchAsync(text);
return await task;
}
}
An element object wraps an PuppeteerSharp.IElementHandle and should encapsulate the way tests interact with an element of a web page.
Create element objects by inheriting ElementObject and declare properties decorated with [Selector] attributes.
public class GitHubHeader : ElementObject
{
[Selector("#query-builder-test")]
public virtual Task<IElementHandle> SearchInput { get; }
public async Task SearchAsync(string text)
{
var input = await SearchInput;
if (await input.IsHiddenAsync())
{
await Page.ClickAsync("[aria-label=\"Toggle navigation\"][data-view-component=\"true\"]");
await Page.ClickAsync("[data-target=\"qbsearch-input.inputButtonText\"]");
}
await input.TypeAsync(text);
await input.PressAsync(Key.Enter);
await Page.WaitForSelectorAsync("[data-testid=\"results-list\"]");
}
}
[Selector] attributes can be applied to properties on a PageObject or ElementObject.
Properties decorated with a [Selector] attribute must be a:
that returns:
Task<IElementHandle>Task<IElementHandle[]>Task<ElementObject> orTask<ElementObject[]>Example:
[Selector("#foo")]
public virtual Task<IElementHandle> SelectorForElementHandle { get; }
[Selector(".bar")]
public virtual Task<IElementHandle[]> SelectorForElementHandleArray { get; }
[Selector("#foo")]
public virtual Task<FooElementObject> SelectorForElementObject { get; }
[Selector(".bar")]
public virtual Task<BarElementObject[]> SelectorForElementObjectArray { get; }
IPageWhere T is a PageObject:
GoBackAsync<T>GoForwardAsync<T>GoToAsync<T>ReloadAsync<T>To<T>WaitForNavigationAsync<T>WaitForResponseAsync<T>Where T is an ElementObject:
QuerySelectorAllAsync<T>QuerySelectorAsync<T>WaitForSelectorAsync<T>WaitForXPathAsync<T>XPathAsync<T>IElementHandleWhere T is an ElementObject:
QuerySelectorAllAsync<T>QuerySelectorAsync<T>To<T>WaitForSelectorAsync<T>XPathAsync<T>A sample project with NUnit is located in the samples folder:
PageObjects.cs contains the page and element objectsPuppeteerSharpRepoPageObjectTests.cs contains the tests using the page object pattern