# Coypu: a Capybara-style browser automation layer for .NET

> Coypu is a.NET wrapper over Selenium or Playwright that lets you drive a browser the way a person would, find elements by their visible text, and stop writing sleeps and XPath in your tests. Its most recent release is 4.2.0, and a Playwright driver is announced as the next default.

**featurist/coypu** — Intuitive, robust browser automation for .Net

- Repository: https://github.com/featurist/coypu
- Stars: 564 · Forks: 135
- Language: C#
- License: MIT
- Published: 2026-10-22 · Updated: 2026-10-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/featurist-coypu

## The pitch is about what your tests look like, not about features

Coypu supports browser automation in .Net to help make tests readable, resilient, fast to write and less tightly coupled to the UI. The README then names the symptom it is for: if your tests are littered with sleeps, retries, complex XPath expressions and IDs dug out of the source with browser developer tools, then Coypu might help.

That is a good description of the problem, because all four items on that list are the same problem seen from different angles. A sleep is there because the test does not know when the page is ready. A retry is there because the test does not know when the click has landed. A complex XPath is there because the test cannot identify the element by anything a person would recognise. And an ID copied out of developer tools breaks the moment a developer changes it.

Coypu is described in two lines in the README. It is a wrapper for browser automation on the .net platform for Selenium WebDriver or Microsoft Playwright that eases automating ajax-heavy websites and reduces coupling to the HTML, CSS and JS. And it is a more intuitive API for interacting with the browser in the way a human being would, inspired by the ruby framework Capybara.

That last sentence is the honest description of the project. Coypu is the Capybara idea, in C#, on top of a .NET driver.

The package is on Nuget as Coypu, with the matchers in a separate Coypu.NUnit package, and the compatibility badge shows .NET Framework 4.5 or later and .NET Standard 2.0. The licence is MIT, the last push was on 2026-09-02, and the most recent tagged release is 4.2.0 from 2024-04-08.

## The API surface is a session you dispose

The browser session is the unit of work, and it is a disposable object. You open one like so:

```c#
var browser = new BrowserSession();
```

And when you are done with it, you dispose it:

```c#
browser.Dispose();
```

Or you scope it with a using block:

```c#
using (var browser = new BrowserSession())
{
	...
}
```

The third form is the one to prefer in a test suite, because a browser session that leaks is a browser process that stays alive, and a suite that leaves browsers behind will eventually exhaust the machine it runs on. The IDisposable contract makes the cleanup something the compiler enforces rather than something a reviewer has to remember.

The matchers are the other half of the API and they live in a separate package, so the core library does not drag in a test framework. The README gives one example, Assert.That(browserSession, Shows.Content("Hello world")), which is an NUnit style assertion against a matcher that checks the visible content of the page. A separate package for the matchers means you can use Coypu from a console application or a script without taking an NUnit dependency, and it means the matcher set is a thing the project can extend on its own schedule.

## Configuration is host, port and SSL, with defaults for everything

You configure Coypu by passing an instance of SessionConfiguration to the constructor of BrowserSession:

```c#
var browserSession = new BrowserSession(new SessionConfiguration{...});
```

The website under test is described with a host, a port and an SSL flag:

```c#
var sessionConfiguration = new SessionConfiguration
{
  AppHost = "autotrader.co.uk",
  Port = 5555,
  SSL = true|false
};
```

If you do not specify any of these, Coypu will default to http, localhost and port 80. So a test against a local instance needs no configuration at all, and a test against a real site needs three lines.

Basic authentication is folded into the host string, which is the part that looks strange until you know it:

```c#
var sessionConfiguration = new SessionConfiguration
{
  AppHost = "username@password:autotrader.co.uk"
};
```

The username and password go before the host, separated by an at sign, with a colon before the domain. That is a compact encoding, and it is the kind of detail that would be worth knowing before you spend an afternoon on a parse error.

## Drivers and browsers, and the move to Playwright

Coypu drivers implement the Coypu.Driver interface and read the SessionConfiguration.Browser setting to pick the correct browser. The default combination is Selenium with Firefox:

```c#
sessionConfiguration.Driver = typeof (Coypu.Drivers.Selenium.SeleniumWebDriver);
sessionConfiguration.Browser = Drivers.Browser.Firefox;
```

If you want to configure these at runtime, you can replace the strings with values read from your environment or configuration, using Type.GetType for the driver and a parse call for the browser:

```c#
sessionConfiguration.Driver = Type.GetType("Coypu.Drivers.Selenium.SeleniumWebDriver, Coypu");
sessionConfiguration.Browser = Drivers.Browser.Parse("firefox");
```

The Playwright driver arrived in Coypu v4.1.0, and the README states plainly that the playwright driver will become the default driver for Coypu in the next major release. The Playwright driver is selected the same way:

```c#
sessionConfiguration.Driver = typeof (Coypu.Drivers.Playwright.PlaywrightDriver);
```

The Playwright browser options are listed as Chromium, Chrome, Edge, Firefox and Webkit, and there is a note that you may need to install the latest Playwright browser binaries using the Playwright CLI, with a link to the .NET documentation on browsers.

So the direction of travel is clear and the project says so. Selenium is the current default, Playwright is the announced next default, and the Selenium driver still has features the Playwright one does not yet cover.

## Headless is where the two drivers differ most

Headless mode is a single setting on the session configuration:

```c#
sessionConfiguration.Headless=true
```

But the two drivers behave very differently there. The README states that the Playwright driver in headless mode passes all the Coypu specs, and that headless Playwright runs up to 5 times faster than headed Selenium.

For Selenium, headless was never enabled because of various shortcomings in the past, and from Coypu v4.1.0 it can be enabled using the Headless setting. The README is specific about the limitation: Selenium does have issues accessing cookies and IFrames in headless mode, so you may need to run tests that rely on these features in headed mode when using the Selenium driver.

That is a real constraint rather than a caveat. A test suite that logs in and then asserts on content in an iframe is exactly the kind of suite that will behave differently in the two drivers, and you will find it when you switch, not before.

Browser support also differs. Selenium only supports headless for Chrome, Edge and Firefox, with IE and Safari not supported. Opera is no longer supported by Selenium at all, since its driver was removed in Selenium 4.2, so Browser.Opera now throws BrowserNotSupportedException on the Selenium driver.

That last point is the clearest signal of the age of the code. A browser that was removed from Selenium in 2021 is still present in the Coypu enum, and it throws rather than being quietly absent.

## Retries are the mechanism, and that has consequences

The waits, retries and timeout section is where the design decision that makes the tests readable turns into a trade-off.

Most of the methods in the Coypu API are automatically retried on any driver error until a configurable timeout is reached. The implementation, as the README describes it, just catches exceptions and retries, mainly the Coypu.Drivers.MissingHtmlException that a driver should throw when an element it was asked to find is not there.

That single mechanism replaces the sleeps and the explicit retry loops. A method that finds an element will wait for it to appear, and a method that clicks will keep trying until the driver stops throwing. Which means the test reads like a person acting on the page, and the waiting is handled once, in the library.

The consequence is that a genuinely broken test takes longer to fail, because every method keeps retrying until the timeout. A test that would have failed in half a second now runs for the configured timeout before reporting, and a suite with a lot of failures takes correspondingly longer to report. That is the price of the readable style, and it is worth knowing when you are looking at a slow suite and wondering why.

The other thing to note is that the retry is on any driver error, not only on a missing element. A timeout that is really a broken selector is retried the same way as a timeout that is a page still loading.

For SpecFlow users, the README notes that you will probably want to configure a single Browser Session scoped to each scenario, using the dependency injection SpecFlow supports, with a gist linked as an example.

## Conclusion

Adopt Coypu if your .NET test suite is full of sleeps, brittle XPath expressions and IDs copied out of developer tools, and you want element lookups that read like the way a user sees the page. Do not adopt it for a new project if you can start with Playwright's own .NET bindings, because Coypu adds a layer over them and the driver choice is moving under you. Before you start, read the headless section, because headless Playwright is stated to pass all the Coypu specs and to run up to five times faster than headed Selenium, while the Selenium driver has known trouble with cookies and iframes in headless mode.

## FAQ

### How do I install Coypu for a .NET project?

Install the main package with `PM> Install-Package Coypu`, and add `PM> Install-Package Coypu.NUnit` if you want the NUnit matchers such as Shows.Content. The package targets .NET Framework 4.5 or later and .NET Standard 2.0.

### How do I configure the site under test in Coypu?

Pass a SessionConfiguration to the BrowserSession constructor with an AppHost, a Port and an SSL flag. If you specify none of them, Coypu defaults to http, localhost and port 80. Basic authentication is folded into the host as a username@password:host string.

### Does Coypu support headless testing, and does it behave the same on both drivers?

Yes, through the sessionConfiguration.Headless setting, but not the same. The README states the Playwright driver in headless mode passes all the Coypu specs and runs up to 5 times faster than headed Selenium, while the Selenium driver has issues accessing cookies and IFrames in headless mode, so those tests may need headed mode.

### How does Coypu handle waiting for elements?

Most API methods are automatically retried on any driver error until a configurable timeout is reached, catching exceptions and retrying, mainly the MissingHtmlException thrown when an element is not found. That removes explicit sleeps and retry loops from the tests, at the cost of a broken test taking the full timeout to fail.

## Sources

- [featurist/coypu on GitHub](https://github.com/featurist/coypu)
- [Issues](https://github.com/featurist/coypu/issues)
- [License: MIT](https://github.com/featurist/coypu/blob/master/LICENSE)
- [README](https://github.com/featurist/coypu/blob/master/README.md)
- [Releases](https://github.com/featurist/coypu/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/featurist-coypu
