But done right this time. Contributions are welcome.
The following test searches for something in Google and asserts that the results are present in both Chrome, Edge and Firefox on Selenium, and Chromium on Puppeteer. All browsers execute their actions in parallel.
var serviceCollection = new ServiceCollection();
serviceCollection.AddJQueryDomSelector();
//use 3 different browsers via Selenium
serviceCollection.AddSeleniumWebAutomationFrameworkInstance(GetEdgeDriver);
serviceCollection.AddSeleniumWebAutomationFrameworkInstance(GetFirefoxDriver);
serviceCollection.AddSeleniumWebAutomationFrameworkInstance(GetChromeDriver);
//also use Chromium via Puppeteer
serviceCollection.AddPuppeteerWebAutomationFrameworkInstance(GetPuppeteerDriverAsync);
var serviceProvider = serviceCollection.BuildServiceProvider();
using (var automationEngine = serviceProvider.GetRequiredService<IWebAutomationEngine>())
{
await automationEngine.InitializeAsync();
await automationEngine
.Open("https://google.com");
await automationEngine
.Enter("this is a very long test that works").In("input[type=text]:visible")
.Wait(until =>
until.Exists("input[type=submit]:visible"));
var elements = await automationEngine
.Click.On("input[type=submit]:visible:first")
.Wait(until =>
until.Exists("#rso .g:visible"))
.Expect
.Count(10).Of("#rso .g:visible");
Console.WriteLine("Test done!");
}
A selector determines how to select elements. Right now, only jQuery selectors are supported.
install-package FluffySpoon.Automation.Css
serviceCollection.AddJQueryDomSelector();
install-package FluffySpoon.Automation.JQuery
serviceCollection.AddCssDomSelector();
An automation framework decides how the automation is done. Can use either Selenium or Puppeteer currently.
install-package FluffySpoon.Automation.Selenium
install-package FluffySpoon.Automation.Puppeteer
await automationEngine.Open("https://example.com");
await automationEngine
.TakeScreenshot
.Of("selector")
.SaveAs((engine, i) =>
engine.UserAgentName + "_" + i + ".jpg");
var elementsClicked = await automationEngine.Click.On("selector");
var elementsClicked = await automationEngine.DoubleClick.On("selector");
var elementsClicked = await automationEngine.RightClick.On("selector");
var elementsHovered = await automationEngine.Hover.On("selector");
var elementsDragged = await automationEngine.Drag.From("selector").To("selector");
var elementsTypedIn = await automationEngine.Enter("some text").In("selector");
var elements = await automationEngine.Find("selector");
Currently only supports a single element.
var elementsFocused = await automationEngine.Focus.On("selector");
await automationEngine.Select.ByTexts("Bar", "Baz", ...).From("selector");
await automationEngine.Select.ByIndices(0, 2, ...).From("selector");
await automationEngine.Select.ByValues("value1", "value2", ...).From("selector");
await automationEngine.Select.ByValues(1337, 1338, ...).From("selector");
await automationEngine.Select.ByText("Bar").From("selector");
await automationEngine.Select.ByIndex(0).From("selector");
await automationEngine.Select.ByValue("value").From("selector");
await automationEngine.Select.ByValue(1337).From("selector");
await automationEngine.Wait(until => until.???);
All methods that are available on the until
object are the same as are available on the Expect
object (see "Expectations" below).
Any expecation made that is not met, will throw an ExpectationNotMetException
. If you want to wait until a specific expectation is met, see "Waiting" above instead.
await automationEngine.Expect.Class.Of("selector");
await automationEngine.Expect.Count(10).Of("selector");
await automationEngine.Expect.Exists.Of("selector");
await automationEngine.Expect.Text("my text").In("selector");
await automationEngine.Expect.Value("value").Of("selector");
Open an issue if there's something missing. I want to make this library the best there is! Pull requests are also very welcome.
There is a known bug in .NET Core that will slow down Selenium, which has a workaround described.
If you see performance issues outside .NET Core or what you are seeing is unrelated, please open an issue.