diff --git a/docs/src/api-testing-csharp.md b/docs/src/api-testing-csharp.md index f68a733322..f68ff8a8f7 100644 --- a/docs/src/api-testing-csharp.md +++ b/docs/src/api-testing-csharp.md @@ -16,7 +16,7 @@ A few examples where it may come in handy: All of that could be achieved via [APIRequestContext] methods. -The following examples rely on the [`Microsoft.Playwright.NUnit`](./test-runners.md) package which creates a Playwright and Page instance for each test. +The following examples rely on the [`Microsoft.Playwright.MSTest`](./test-runners.md) package which creates a Playwright and Page instance for each test. @@ -34,22 +34,19 @@ The following example demonstrates how to use Playwright to test issues creation GitHub API requires authorization, so we'll configure the token once for all tests. While at it, we'll also set the `baseURL` to simplify the tests. ```csharp -using System; -using System.Collections.Generic; -using System.Threading.Tasks; -using Microsoft.Playwright.NUnit; using Microsoft.Playwright; -using NUnit.Framework; +using Microsoft.Playwright.MSTest; namespace PlaywrightTests; +[TestClass] public class TestGitHubAPI : PlaywrightTest { - static string API_TOKEN = Environment.GetEnvironmentVariable("GITHUB_API_TOKEN"); + static string? API_TOKEN = Environment.GetEnvironmentVariable("GITHUB_API_TOKEN"); - private IAPIRequestContext Request = null; + private IAPIRequestContext Request = null!; - [SetUp] + [TestInitialize] public async Task SetUpAPITesting() { await CreateAPIRequestContext(); @@ -71,7 +68,7 @@ public class TestGitHubAPI : PlaywrightTest }); } - [TearDown] + [TestCleanup] public async Task TearDownAPITesting() { await Request.DisposeAsync(); @@ -83,36 +80,34 @@ public class TestGitHubAPI : PlaywrightTest Now that we initialized request object we can add a few tests that will create new issues in the repository. ```csharp -using System; -using System.Collections.Generic; -using System.Threading.Tasks; using System.Text.Json; -using Microsoft.Playwright.NUnit; using Microsoft.Playwright; -using NUnit.Framework; +using Microsoft.Playwright.MSTest; namespace PlaywrightTests; -[TestFixture] +[TestClass] public class TestGitHubAPI : PlaywrightTest { - static string REPO = "test-repo-2"; + static string REPO = "test"; static string USER = Environment.GetEnvironmentVariable("GITHUB_USER"); - static string API_TOKEN = Environment.GetEnvironmentVariable("GITHUB_API_TOKEN"); + static string? API_TOKEN = Environment.GetEnvironmentVariable("GITHUB_API_TOKEN"); - private IAPIRequestContext Request = null; + private IAPIRequestContext Request = null!; - [Test] + [TestMethod] public async Task ShouldCreateBugReport() { - var data = new Dictionary(); - data.Add("title", "[Bug] report 1"); - data.Add("body", "Bug description"); + var data = new Dictionary + { + { "title", "[Bug] report 1" }, + { "body", "Bug description" } + }; var newIssue = await Request.PostAsync("/repos/" + USER + "/" + REPO + "/issues", new() { DataObject = data }); - Assert.True(newIssue.Ok); + await Expect(newIssue).ToBeOKAsync(); var issues = await Request.GetAsync("/repos/" + USER + "/" + REPO + "/issues"); - Assert.True(issues.Ok); + await Expect(newIssue).ToBeOKAsync(); var issuesJsonResponse = await issues.JsonAsync(); JsonElement? issue = null; foreach (JsonElement issueObj in issuesJsonResponse?.EnumerateArray()) @@ -125,23 +120,24 @@ public class TestGitHubAPI : PlaywrightTest } } } - Assert.NotNull(issue); + Assert.IsNotNull(issue); Assert.AreEqual("Bug description", issue?.GetProperty("body").GetString()); } - [Test] + [TestMethod] public async Task ShouldCreateFeatureRequests() { - var data = new Dictionary(); - data.Add("title", "[Feature] request 1"); - data.Add("body", "Feature description"); + var data = new Dictionary + { + { "title", "[Feature] request 1" }, + { "body", "Feature description" } + }; var newIssue = await Request.PostAsync("/repos/" + USER + "/" + REPO + "/issues", new() { DataObject = data }); - Assert.True(newIssue.Ok); + await Expect(newIssue).ToBeOKAsync(); var issues = await Request.GetAsync("/repos/" + USER + "/" + REPO + "/issues"); - Assert.True(issues.Ok); + await Expect(newIssue).ToBeOKAsync(); var issuesJsonResponse = await issues.JsonAsync(); - var issuesJson = (await issues.JsonAsync())?.EnumerateArray(); JsonElement? issue = null; foreach (JsonElement issueObj in issuesJsonResponse?.EnumerateArray()) @@ -154,7 +150,7 @@ public class TestGitHubAPI : PlaywrightTest } } } - Assert.NotNull(issue); + Assert.IsNotNull(issue); Assert.AreEqual("Feature description", issue?.GetProperty("body").GetString()); } @@ -167,41 +163,47 @@ public class TestGitHubAPI : PlaywrightTest These tests assume that repository exists. You probably want to create a new one before running tests and delete it afterwards. Use `[SetUp]` and `[TearDown]` hooks for that. ```csharp +using System.Text.Json; +using Microsoft.Playwright; +using Microsoft.Playwright.MSTest; + +namespace PlaywrightTests; + +[TestClass] public class TestGitHubAPI : PlaywrightTest { - // ... + // ... + [TestInitialize] + public async Task SetUpAPITesting() + { + await CreateAPIRequestContext(); + await CreateTestRepository(); + } - [SetUp] - public async Task SetUpAPITesting() - { - await CreateAPIRequestContext(); - await CreateTestRepository(); - } + private async Task CreateTestRepository() + { + var resp = await Request.PostAsync("/user/repos", new() + { + DataObject = new Dictionary() + { + ["name"] = REPO, + }, + }); + await Expect(resp).ToBeOKAsync(); + } - private async Task CreateTestRepository() - { - var resp = await Request.PostAsync("/user/repos", new() - { - DataObject = new Dictionary() - { - ["name"] = REPO, - }, - }); - Assert.True(resp.Ok); - } + [TestCleanup] + public async Task TearDownAPITesting() + { + await DeleteTestRepository(); + await Request.DisposeAsync(); + } - [TearDown] - public async Task TearDownAPITesting() - { - await DeleteTestRepository(); - await Request.DisposeAsync(); - } - - private async Task DeleteTestRepository() - { - var resp = await Request.DeleteAsync("/repos/" + USER + "/" + REPO); - Assert.True(resp.Ok); - } + private async Task DeleteTestRepository() + { + var resp = await Request.DeleteAsync("/repos/" + USER + "/" + REPO); + await Expect(resp).ToBeOKAsync(); + } } ``` @@ -210,36 +212,34 @@ public class TestGitHubAPI : PlaywrightTest Here is the complete example of an API test: ```csharp -using System; -using System.Collections.Generic; -using System.Threading.Tasks; using System.Text.Json; -using Microsoft.Playwright.NUnit; using Microsoft.Playwright; -using NUnit.Framework; +using Microsoft.Playwright.MSTest; namespace PlaywrightTests; -[TestFixture] +[TestClass] public class TestGitHubAPI : PlaywrightTest { static string REPO = "test-repo-2"; static string USER = Environment.GetEnvironmentVariable("GITHUB_USER"); - static string API_TOKEN = Environment.GetEnvironmentVariable("GITHUB_API_TOKEN"); + static string? API_TOKEN = Environment.GetEnvironmentVariable("GITHUB_API_TOKEN"); - private IAPIRequestContext Request = null; + private IAPIRequestContext Request = null!; - [Test] + [TestMethod] public async Task ShouldCreateBugReport() { - var data = new Dictionary(); - data.Add("title", "[Bug] report 1"); - data.Add("body", "Bug description"); + var data = new Dictionary + { + { "title", "[Bug] report 1" }, + { "body", "Bug description" } + }; var newIssue = await Request.PostAsync("/repos/" + USER + "/" + REPO + "/issues", new() { DataObject = data }); - Assert.True(newIssue.Ok); + await Expect(newIssue).ToBeOKAsync(); var issues = await Request.GetAsync("/repos/" + USER + "/" + REPO + "/issues"); - Assert.True(issues.Ok); + await Expect(newIssue).ToBeOKAsync(); var issuesJsonResponse = await issues.JsonAsync(); JsonElement? issue = null; foreach (JsonElement issueObj in issuesJsonResponse?.EnumerateArray()) @@ -252,23 +252,24 @@ public class TestGitHubAPI : PlaywrightTest } } } - Assert.NotNull(issue); + Assert.IsNotNull(issue); Assert.AreEqual("Bug description", issue?.GetProperty("body").GetString()); } - [Test] + [TestMethod] public async Task ShouldCreateFeatureRequests() { - var data = new Dictionary(); - data.Add("title", "[Feature] request 1"); - data.Add("body", "Feature description"); + var data = new Dictionary + { + { "title", "[Feature] request 1" }, + { "body", "Feature description" } + }; var newIssue = await Request.PostAsync("/repos/" + USER + "/" + REPO + "/issues", new() { DataObject = data }); - Assert.True(newIssue.Ok); + await Expect(newIssue).ToBeOKAsync(); var issues = await Request.GetAsync("/repos/" + USER + "/" + REPO + "/issues"); - Assert.True(issues.Ok); + await Expect(newIssue).ToBeOKAsync(); var issuesJsonResponse = await issues.JsonAsync(); - var issuesJson = (await issues.JsonAsync())?.EnumerateArray(); JsonElement? issue = null; foreach (JsonElement issueObj in issuesJsonResponse?.EnumerateArray()) @@ -281,11 +282,11 @@ public class TestGitHubAPI : PlaywrightTest } } } - Assert.NotNull(issue); + Assert.IsNotNull(issue); Assert.AreEqual("Feature description", issue?.GetProperty("body").GetString()); } - [SetUp] + [TestInitialize] public async Task SetUpAPITesting() { await CreateAPIRequestContext(); @@ -294,14 +295,16 @@ public class TestGitHubAPI : PlaywrightTest private async Task CreateAPIRequestContext() { - var headers = new Dictionary(); - // We set this header per GitHub guidelines. - headers.Add("Accept", "application/vnd.github.v3+json"); - // Add authorization token to all requests. - // Assuming personal access token available in the environment. - headers.Add("Authorization", "token " + API_TOKEN); + var headers = new Dictionary + { + // We set this header per GitHub guidelines. + { "Accept", "application/vnd.github.v3+json" }, + // Add authorization token to all requests. + // Assuming personal access token available in the environment. + { "Authorization", "token " + API_TOKEN } + }; - Request = await this.Playwright.APIRequest.NewContextAsync(new() + Request = await Playwright.APIRequest.NewContextAsync(new() { // All requests we send go to this API endpoint. BaseURL = "https://api.github.com", @@ -318,10 +321,10 @@ public class TestGitHubAPI : PlaywrightTest ["name"] = REPO, }, }); - Assert.True(resp.Ok); + await Expect(resp).ToBeOKAsync(); } - [TearDown] + [TestCleanup] public async Task TearDownAPITesting() { await DeleteTestRepository(); @@ -331,7 +334,7 @@ public class TestGitHubAPI : PlaywrightTest private async Task DeleteTestRepository() { var resp = await Request.DeleteAsync("/repos/" + USER + "/" + REPO); - Assert.True(resp.Ok); + await Expect(resp).ToBeOKAsync(); } } ``` @@ -344,21 +347,23 @@ project to check that it appears at the top of the list. The check is performed ```csharp class TestGitHubAPI : PageTest { - [Test] - public async Task LastCreatedIssueShouldBeFirstInTheList() - { - var data = new Dictionary(); - data.Add("title", "[Feature] request 1"); - data.Add("body", "Feature description"); - var newIssue = await Request.PostAsync("/repos/" + USER + "/" + REPO + "/issues", new() { DataObject = data }); - Assert.True(newIssue.Ok); + [TestMethod] + public async Task LastCreatedIssueShouldBeFirstInTheList() + { + var data = new Dictionary + { + { "title", "[Feature] request 1" }, + { "body", "Feature description" } + }; + var newIssue = await Request.PostAsync("/repos/" + USER + "/" + REPO + "/issues", new() { DataObject = data }); + await Expect(newIssue).ToBeOKAsync(); - // When inheriting from 'PlaywrightTest' it only gives you a Playwright instance. To get a Page instance, either start - // a browser, context, and page manually or inherit from 'PageTest' which will launch it for you. - await Page.GotoAsync("https://github.com/" + USER + "/" + REPO + "/issues"); - var firstIssue = Page.Locator("a[data-hovercard-type='issue']").First; - await Expect(firstIssue).ToHaveTextAsync("[Feature] request 1"); - } + // When inheriting from 'PlaywrightTest' it only gives you a Playwright instance. To get a Page instance, either start + // a browser, context, and page manually or inherit from 'PageTest' which will launch it for you. + await Page.GotoAsync("https://github.com/" + USER + "/" + REPO + "/issues"); + var firstIssue = Page.Locator("a[data-hovercard-type='issue']").First; + await Expect(firstIssue).ToHaveTextAsync("[Feature] request 1"); + } } ``` @@ -368,22 +373,23 @@ The following test creates a new issue via user interface in the browser and the it was created: ```csharp +// Make sure to extend from PageTest if you want to use the Page class. class GitHubTests : PageTest { - [Test] - public async Task LastCreatedIssueShouldBeOnTheServer() - { - await Page.GotoAsync("https://github.com/" + USER + "/" + REPO + "/issues"); - await Page.Locator("text=New Issue").ClickAsync(); - await Page.Locator("[aria-label='Title']").FillAsync("Bug report 1"); - await Page.Locator("[aria-label='Comment body']").FillAsync("Bug description"); - await Page.Locator("text=Submit new issue").ClickAsync(); - String issueId = Page.Url.Substring(Page.Url.LastIndexOf('/')); + [TestMethod] + public async Task LastCreatedIssueShouldBeOnTheServer() + { + await Page.GotoAsync("https://github.com/" + USER + "/" + REPO + "/issues"); + await Page.Locator("text=New Issue").ClickAsync(); + await Page.Locator("[aria-label='Title']").FillAsync("Bug report 1"); + await Page.Locator("[aria-label='Comment body']").FillAsync("Bug description"); + await Page.Locator("text=Submit new issue").ClickAsync(); + var issueId = Page.Url.Substring(Page.Url.LastIndexOf('/')); - var newIssue = await Request.GetAsync("https://github.com/" + USER + "/" + REPO + "/issues/" + issueId); - Assert.True(newIssue.Ok); - StringAssert.Contains(await newIssue.TextAsync(), "Bug report 1"); - } + var newIssue = await Request.GetAsync("https://github.com/" + USER + "/" + REPO + "/issues/" + issueId); + await Expect(newIssue).ToBeOKAsync(); + StringAssert.Contains(await newIssue.TextAsync(), "Bug report 1"); + } } ``` diff --git a/docs/src/api/class-locatorassertions.md b/docs/src/api/class-locatorassertions.md index c06f906e3d..1ff5e52119 100644 --- a/docs/src/api/class-locatorassertions.md +++ b/docs/src/api/class-locatorassertions.md @@ -47,21 +47,19 @@ def test_status_becomes_submitted(page: Page) -> None: ``` ```csharp -using System.Text.RegularExpressions; -using System.Threading.Tasks; -using Microsoft.Playwright.NUnit; -using NUnit.Framework; +using Microsoft.Playwright; +using Microsoft.Playwright.MSTest; namespace PlaywrightTests; -[TestFixture] +[TestClass] public class ExampleTests : PageTest { - [Test] + [TestMethod] public async Task StatusBecomesSubmitted() { - // .. - await Page.GetByRole(AriaRole.Button).ClickAsync(); + // ... + await Page.GetByRole(AriaRole.Button, new() { Name = "Sign In" }).ClickAsync(); await Expect(Page.Locator(".status")).ToHaveTextAsync("Submitted"); } } diff --git a/docs/src/api/class-pageassertions.md b/docs/src/api/class-pageassertions.md index db9b0da236..51076e5e07 100644 --- a/docs/src/api/class-pageassertions.md +++ b/docs/src/api/class-pageassertions.md @@ -50,21 +50,19 @@ def test_navigates_to_login_page(page: Page) -> None: ```csharp using System.Text.RegularExpressions; -using System.Threading.Tasks; -using Microsoft.Playwright.NUnit; -using NUnit.Framework; +using Microsoft.Playwright; +using Microsoft.Playwright.MSTest; namespace PlaywrightTests; -[TestFixture] +[TestClass] public class ExampleTests : PageTest { - [Test] + [TestMethod] public async Task NavigatetoLoginPage() { - // .. - await Page.GetByText("Sing in").ClickAsync(); - await Expect(Page.Locator("div#foobar")).ToHaveURL(new Regex(".*/login")); + await Page.GetByRole(AriaRole.Button, new() { Name = "Sign In" }).ClickAsync(); + await Expect(Page).ToHaveURLAsync(new Regex(".*/login")); } } ``` diff --git a/docs/src/api/class-playwrightassertions.md b/docs/src/api/class-playwrightassertions.md index 0d8a2c9ce8..7a960e34e1 100644 --- a/docs/src/api/class-playwrightassertions.md +++ b/docs/src/api/class-playwrightassertions.md @@ -50,19 +50,18 @@ public class TestExample { ``` ```csharp -using System.Threading.Tasks; -using Microsoft.Playwright.NUnit; -using NUnit.Framework; +using Microsoft.Playwright; +using Microsoft.Playwright.MSTest; namespace PlaywrightTests; -[TestFixture] +[TestClass] public class ExampleTests : PageTest { - [Test] + [TestMethod] public async Task StatusBecomesSubmitted() { - await Page.Locator("#submit-button").ClickAsync(); + await Page.GetByRole(AriaRole.Button, new() { Name = "Submit" }).ClickAsync(); await Expect(Page.Locator(".status")).ToHaveTextAsync("Submitted"); } } diff --git a/docs/src/intro-csharp.md b/docs/src/intro-csharp.md index 91f8a967b0..61136782ec 100644 --- a/docs/src/intro-csharp.md +++ b/docs/src/intro-csharp.md @@ -7,16 +7,16 @@ title: "Installation" Playwright was created specifically to accommodate the needs of end-to-end testing. Playwright supports all modern rendering engines including Chromium, WebKit, and Firefox. Test on Windows, Linux, and macOS, locally or on CI, headless or headed with native mobile emulation. -You can choose to use [NUnit base classes](./test-runners.md#nunit) or [MSTest base classes](./test-runners.md#mstest) that Playwright provides to write end-to-end tests. These classes support running tests on multiple browser engines, parallelizing tests, adjusting launch/context options and getting a [Page]/[BrowserContext] instance per test out of the box. Alternatively you can use the [library](./library.md) to manually write the testing infrastructure. +You can choose to use [MSTest base classes](./test-runners.md#mstest) or [NUnit base classes](./test-runners.md#nunit) that Playwright provides to write end-to-end tests. These classes support running tests on multiple browser engines, parallelizing tests, adjusting launch/context options and getting a [Page]/[BrowserContext] instance per test out of the box. Alternatively you can use the [library](./library.md) to manually write the testing infrastructure. 1. Start by creating a new project with `dotnet new`. This will create the `PlaywrightTests` directory which includes a `UnitTest1.cs` file: @@ -41,10 +41,10 @@ cd PlaywrightTests @@ -83,10 +83,10 @@ Edit the `UnitTest1.cs` file with the code below to create an example end-to-end @@ -132,10 +132,8 @@ public class ExampleTest : PageTest ```csharp title="UnitTest1.cs" using System.Text.RegularExpressions; -using System.Threading.Tasks; using Microsoft.Playwright; using Microsoft.Playwright.MSTest; -using Microsoft.VisualStudio.TestTools.UnitTesting; namespace PlaywrightTests; @@ -192,4 +190,4 @@ See our doc on [Running and Debugging Tests](./running-tests.md) to learn more a - [Generate tests with Codegen](./codegen-intro.md) - [See a trace of your tests](./trace-viewer-intro.md) - [Run tests on CI](./ci-intro.md) -- [Learn more about the NUnit and MSTest base classes](./test-runners.md) +- [Learn more about the MSTest and NUnit base classes](./test-runners.md) diff --git a/docs/src/languages.md b/docs/src/languages.md index a84167fe97..050c1597b3 100644 --- a/docs/src/languages.md +++ b/docs/src/languages.md @@ -30,7 +30,7 @@ You can choose any testing framework such as JUnit or TestNG based on your proje ## .NET -Playwright for .NET comes with [NUnit base classes](https://playwright.dev/dotnet/docs/test-runners#nunit) and [MSTest base classes](https://playwright.dev/dotnet/docs/test-runners#mstest) for writing end-to-end tests. +Playwright for .NET comes with [MSTest base classes](https://playwright.dev/dotnet/docs/test-runners#mstest) and [NUnit base classes](https://playwright.dev/dotnet/docs/test-runners#nunit) for writing end-to-end tests. * [Documentation](https://playwright.dev/dotnet/docs/intro) * [GitHub repo](https://github.com/microsoft/playwright-dotnet) diff --git a/docs/src/library-csharp.md b/docs/src/library-csharp.md index 5dab997f7e..c659cbf1ee 100644 --- a/docs/src/library-csharp.md +++ b/docs/src/library-csharp.md @@ -5,7 +5,7 @@ title: "Getting started - Library" ## Introduction -Playwright can either be used with the [NUnit](./test-runners.md#nunit) or [MSTest](./test-runners.md#mstest), or as a Playwright Library (this guide). If you are working on an application that utilizes Playwright capabilities or you are using Playwright with another test runner, read on. +Playwright can either be used with the [MSTest](./test-runners.md#mstest) or [NUnit](./test-runners.md#nunit), or as a Playwright Library (this guide). If you are working on an application that utilizes Playwright capabilities or you are using Playwright with another test runner, read on. ## Usage diff --git a/docs/src/release-notes-csharp.md b/docs/src/release-notes-csharp.md index 54d91386cb..9a3301a764 100644 --- a/docs/src/release-notes-csharp.md +++ b/docs/src/release-notes-csharp.md @@ -637,7 +637,7 @@ This version was also tested against the following stable channels: ### Other highlights - New option `MaxRedirects` for [`method: APIRequestContext.get`] and others to limit redirect count. -- Codegen now supports NUnit and MSTest frameworks. +- Codegen now supports MSTest and NUnit frameworks. - ASP .NET is now supported. ### Behavior Change diff --git a/docs/src/running-tests-csharp.md b/docs/src/running-tests-csharp.md index 6bfbcb56bb..d366526f26 100644 --- a/docs/src/running-tests-csharp.md +++ b/docs/src/running-tests-csharp.md @@ -109,10 +109,10 @@ dotnet test --filter "Name~GetStartedLink" @@ -159,4 +159,4 @@ Check out our [debugging guide](./debug.md) to learn more about the [Playwright - [Generate tests with Codegen](./codegen-intro.md) - [See a trace of your tests](./trace-viewer-intro.md) - [Run tests on CI](./ci-intro.md) -- [Learn more about the NUnit and MSTest base classes](./test-runners.md) +- [Learn more about the MSTest and NUnit base classes](./test-runners.md) diff --git a/docs/src/test-assertions-csharp-java-python.md b/docs/src/test-assertions-csharp-java-python.md index 2ab57e40b2..3e8e634a07 100644 --- a/docs/src/test-assertions-csharp-java-python.md +++ b/docs/src/test-assertions-csharp-java-python.md @@ -77,10 +77,10 @@ expect.set_options(timeout=10_000) diff --git a/docs/src/test-runners-csharp.md b/docs/src/test-runners-csharp.md index c6824e2302..74c0f0ff08 100644 --- a/docs/src/test-runners-csharp.md +++ b/docs/src/test-runners-csharp.md @@ -5,135 +5,12 @@ title: "Test Runners" ## Introduction -While Playwright for .NET isn't tied to a particular test runner or testing framework, in our experience it works best with the built-in .NET test runner, and using NUnit as the test framework. NUnit is also what we use internally for [our tests](https://github.com/microsoft/playwright-dotnet/tree/main/src/Playwright.Tests). +While Playwright for .NET isn't tied to a particular test runner or testing framework, in our experience the easiest way of getting started is by using the base classes we provide for [MSTest](#mstest) and [NUnit](#nunit). These classes support running tests on multiple browser engines, adjusting launch/context options and getting a [Page]/[BrowserContext] instance per test out of the box. -Playwright and Browser instances can be reused between tests for better performance. We +Playwright and Browser instances will be reused between tests for better performance. We recommend running each test case in a new BrowserContext, this way browser state will be isolated between the tests. - -## NUnit - -Playwright provides base classes to write tests with NUnit via the [`Microsoft.Playwright.NUnit`](https://www.nuget.org/packages/Microsoft.Playwright.NUnit) package. - -Check out the [installation guide](./intro.md) to get started. - -### Running NUnit tests in Parallel - -By default NUnit will run all test files in parallel, while running tests inside each file sequentially (`ParallelScope.Self`). It will create as many processes as there are cores on the host system. You can adjust this behavior using the NUnit.NumberOfTestWorkers parameter. -Only `ParallelScope.Self` is supported. - -For CPU-bound tests, we recommend using as many workers as there are cores on your system, divided by 2. For IO-bound tests you can use as many workers as you have cores. - -```bash -dotnet test -- NUnit.NumberOfTestWorkers=5 -``` - -### Customizing [BrowserContext] options - -To customize context options, you can override the `ContextOptions` method of your test class derived from `Microsoft.Playwright.MSTest.PageTest` or `Microsoft.Playwright.MSTest.ContextTest`. See the following example: - -```csharp -using Microsoft.Playwright.NUnit; - -namespace PlaywrightTests; - -[Parallelizable(ParallelScope.Self)] -[TestFixture] -public class MyTest : PageTest -{ - [Test] - public async Task TestWithCustomContextOptions() - { - // The following Page (and BrowserContext) instance has the custom colorScheme, viewport and baseURL set: - await Page.GotoAsync("/login"); - } - - public override BrowserNewContextOptions ContextOptions() - { - return new BrowserNewContextOptions() - { - ColorScheme = ColorScheme.Light, - ViewportSize = new() - { - Width = 1920, - Height = 1080 - }, - BaseURL = "https://github.com", - }; - } -} -``` - -### Customizing [Browser]/launch options - -[Browser]/launch options can be overridden either using a run settings file or by setting the run settings options directly via the -CLI. See the following example: - -```xml - - - - chromium - - false - msedge - - - -``` - -```bash -dotnet test -- Playwright.BrowserName=chromium Playwright.LaunchOptions.Headless=false Playwright.LaunchOptions.Channel=msedge -``` - -### Using Verbose API Logs - -When you have enabled the [verbose API log](./debug.md#verbose-api-logs), via the `DEBUG` environment variable, you will see the messages in the standard error stream. In NUnit, within Visual Studio, that will be the `Tests` pane of the `Output` window. It will also be displayed in the `Test Log` for each test. - -### Using the .runsettings file - -When running tests from Visual Studio, you can take advantage of the `.runsettings` file. The following shows a reference of the supported values. - -For example, to specify the amount of workers you can use `NUnit.NumberOfTestWorkers` or to enable `DEBUG` logs `RunConfiguration.EnvironmentVariables`. - -```xml - - - - - 24 - - - - - - pw:api - - - - - chromium - 5000 - - false - msedge - - - -``` - -### Base NUnit classes for Playwright - -There are a few base classes available to you in `Microsoft.Playwright.NUnit` namespace: - -|Test |Description| -|--------------|-----------| -|PageTest |Each test gets a fresh copy of a web [Page] created in its own unique [BrowserContext]. Extending this class is the simplest way of writing a fully-functional Playwright test.



Note: You can override the `ContextOptions` method in each test file to control context options, the ones typically passed into the [`method: Browser.newContext`] method. That way you can specify all kinds of emulation options for your test file individually.| -|ContextTest |Each test will get a fresh copy of a [BrowserContext]. You can create as many pages in this context as you'd like. Using this test is the easiest way to test multi-page scenarios where you need more than one tab.



Note: You can override the `ContextOptions` method in each test file to control context options, the ones typically passed into the [`method: Browser.newContext`] method. That way you can specify all kinds of emulation options for your test file individually.| -|BrowserTest |Each test will get a browser and can create as many contexts as it likes. Each test is responsible for cleaning up all the contexts it created.| -|PlaywrightTest|This gives each test a Playwright object so that the test could start and stop as many browsers as it likes.| - ## MSTest Playwright provides base classes to write tests with MSTest via the [`Microsoft.Playwright.MSTest`](https://www.nuget.org/packages/Microsoft.Playwright.MSTest) package. @@ -259,6 +136,128 @@ There are a few base classes available to you in `Microsoft.Playwright.MSTest` n |BrowserTest |Each test will get a browser and can create as many contexts as it likes. Each test is responsible for cleaning up all the contexts it created.| |PlaywrightTest|This gives each test a Playwright object so that the test could start and stop as many browsers as it likes.| +## NUnit + +Playwright provides base classes to write tests with NUnit via the [`Microsoft.Playwright.NUnit`](https://www.nuget.org/packages/Microsoft.Playwright.NUnit) package. + +Check out the [installation guide](./intro.md) to get started. + +### Running NUnit tests in Parallel + +By default NUnit will run all test files in parallel, while running tests inside each file sequentially (`ParallelScope.Self`). It will create as many processes as there are cores on the host system. You can adjust this behavior using the NUnit.NumberOfTestWorkers parameter. +Only `ParallelScope.Self` is supported. + +For CPU-bound tests, we recommend using as many workers as there are cores on your system, divided by 2. For IO-bound tests you can use as many workers as you have cores. + +```bash +dotnet test -- NUnit.NumberOfTestWorkers=5 +``` + +### Customizing [BrowserContext] options + +To customize context options, you can override the `ContextOptions` method of your test class derived from `Microsoft.Playwright.MSTest.PageTest` or `Microsoft.Playwright.MSTest.ContextTest`. See the following example: + +```csharp +using Microsoft.Playwright.NUnit; + +namespace PlaywrightTests; + +[Parallelizable(ParallelScope.Self)] +[TestFixture] +public class MyTest : PageTest +{ + [Test] + public async Task TestWithCustomContextOptions() + { + // The following Page (and BrowserContext) instance has the custom colorScheme, viewport and baseURL set: + await Page.GotoAsync("/login"); + } + + public override BrowserNewContextOptions ContextOptions() + { + return new BrowserNewContextOptions() + { + ColorScheme = ColorScheme.Light, + ViewportSize = new() + { + Width = 1920, + Height = 1080 + }, + BaseURL = "https://github.com", + }; + } +} +``` + +### Customizing [Browser]/launch options + +[Browser]/launch options can be overridden either using a run settings file or by setting the run settings options directly via the +CLI. See the following example: + +```xml + + + + chromium + + false + msedge + + + +``` + +```bash +dotnet test -- Playwright.BrowserName=chromium Playwright.LaunchOptions.Headless=false Playwright.LaunchOptions.Channel=msedge +``` + +### Using Verbose API Logs + +When you have enabled the [verbose API log](./debug.md#verbose-api-logs), via the `DEBUG` environment variable, you will see the messages in the standard error stream. In NUnit, within Visual Studio, that will be the `Tests` pane of the `Output` window. It will also be displayed in the `Test Log` for each test. + +### Using the .runsettings file + +When running tests from Visual Studio, you can take advantage of the `.runsettings` file. The following shows a reference of the supported values. + +For example, to specify the amount of workers you can use `NUnit.NumberOfTestWorkers` or to enable `DEBUG` logs `RunConfiguration.EnvironmentVariables`. + +```xml + + + + + 24 + + + + + + pw:api + + + + + chromium + 5000 + + false + msedge + + + +``` + +### Base NUnit classes for Playwright + +There are a few base classes available to you in `Microsoft.Playwright.NUnit` namespace: + +|Test |Description| +|--------------|-----------| +|PageTest |Each test gets a fresh copy of a web [Page] created in its own unique [BrowserContext]. Extending this class is the simplest way of writing a fully-functional Playwright test.



Note: You can override the `ContextOptions` method in each test file to control context options, the ones typically passed into the [`method: Browser.newContext`] method. That way you can specify all kinds of emulation options for your test file individually.| +|ContextTest |Each test will get a fresh copy of a [BrowserContext]. You can create as many pages in this context as you'd like. Using this test is the easiest way to test multi-page scenarios where you need more than one tab.



Note: You can override the `ContextOptions` method in each test file to control context options, the ones typically passed into the [`method: Browser.newContext`] method. That way you can specify all kinds of emulation options for your test file individually.| +|BrowserTest |Each test will get a browser and can create as many contexts as it likes. Each test is responsible for cleaning up all the contexts it created.| +|PlaywrightTest|This gives each test a Playwright object so that the test could start and stop as many browsers as it likes.| + ## xUnit support While using xUnit is also supported, we do not support running parallel tests. This is a well known problem/design limitation diff --git a/docs/src/trace-viewer-intro-csharp.md b/docs/src/trace-viewer-intro-csharp.md index 3c64c91f5e..79e560862c 100644 --- a/docs/src/trace-viewer-intro-csharp.md +++ b/docs/src/trace-viewer-intro-csharp.md @@ -18,10 +18,10 @@ Traces can be recorded using the [`property: BrowserContext.tracing`] API as fol @@ -134,4 +134,4 @@ Check out our detailed guide on [Trace Viewer](/trace-viewer.md) to learn more a ## What's next - [Run tests on CI with GitHub Actions](/ci-intro.md) -- [Learn more about the NUnit and MSTest base classes](./test-runners.md) +- [Learn more about the MSTest and NUnit base classes](./test-runners.md) diff --git a/docs/src/trace-viewer.md b/docs/src/trace-viewer.md index 90ec4a5e7c..556b22729a 100644 --- a/docs/src/trace-viewer.md +++ b/docs/src/trace-viewer.md @@ -244,10 +244,10 @@ Traces can be recorded using the [`property: BrowserContext.tracing`] API as fol @@ -355,10 +355,10 @@ Setup your tests to record a trace only when the test fails: diff --git a/docs/src/webview2.md b/docs/src/webview2.md index 573f8369f4..7aef7216ca 100644 --- a/docs/src/webview2.md +++ b/docs/src/webview2.md @@ -347,14 +347,14 @@ def test_webview2(page: Page): ```csharp // WebView2Test.cs -using System.Text.RegularExpressions; -using Microsoft.Playwright.NUnit; -using Microsoft.Playwright; using System.Diagnostics; +using Microsoft.Playwright; +using Microsoft.Playwright.MSTest; -namespace dotnet_nunit; +namespace PlaywrightTests; -public class WebView2Test : PlaywrightTest +[TestClass] +public class ExampleTest : PlaywrightTest { public IBrowser Browser { get; internal set; } = null!; public IBrowserContext Context { get; internal set; } = null!; @@ -363,12 +363,12 @@ public class WebView2Test : PlaywrightTest private string _userDataDir = null!; private string _executablePath = Path.Join(Directory.GetCurrentDirectory(), @"..\..\..\..\webview2-app\bin\Debug\net8.0-windows\webview2.exe"); - [SetUp] - public async Task BrowserSetUp() + [TestInitialize] + public async Task BrowserTestInitialize() { var cdpPort = 10000 + WorkerIndex; Assert.IsTrue(File.Exists(_executablePath), "Make sure that the executable exists"); - _userDataDir = Path.Join(Path.GetTempPath(), $"playwright-webview2-tests/user-data-dir-{TestContext.CurrentContext.WorkerId}"); + _userDataDir = Path.Join(Path.GetTempPath(), $"playwright-webview2-tests/user-data-dir-{WorkerIndex}"); // WebView2 does some lazy cleanups on shutdown so we can't clean it up after each test if (Directory.Exists(_userDataDir)) { @@ -401,8 +401,8 @@ public class WebView2Test : PlaywrightTest Page = Context.Pages[0]; } - [TearDown] - public async Task BrowserTearDown() + [TestCleanup] + public async Task BrowserTestCleanup() { _webView2Process!.Kill(true); await Browser.CloseAsync(); @@ -412,14 +412,15 @@ public class WebView2Test : PlaywrightTest ```csharp // UnitTest1.cs -using Microsoft.Playwright.NUnit; +using Microsoft.Playwright; +using Microsoft.Playwright.MSTest; -namespace dotnet_nunit; +namespace PlaywrightTests; -[Parallelizable(ParallelScope.Self)] -public class Tests : WebView2Test +[TestClass] +public class ExampleTest : WebView2Test { - [Test] + [TestMethod] public async Task HomepageHasPlaywrightInTitleAndGetStartedLinkLinkingtoTheIntroPage() { await Page.GotoAsync("https://playwright.dev"); diff --git a/docs/src/writing-tests-csharp.md b/docs/src/writing-tests-csharp.md index 4b8b760131..f6324be9f1 100644 --- a/docs/src/writing-tests-csharp.md +++ b/docs/src/writing-tests-csharp.md @@ -35,10 +35,10 @@ Take a look at the following example to see how to write a test. @@ -200,10 +200,10 @@ The Playwright NUnit and MSTest test framework base classes will isolate each te @@ -257,10 +257,10 @@ You can use `SetUp`/`TearDown` in NUnit or `TestInitialize`/`TestCleanup` in MST @@ -328,4 +328,4 @@ public class ExampleTest : PageTest - [Generate tests with Codegen](./codegen-intro.md) - [See a trace of your tests](./trace-viewer-intro.md) - [Run tests on CI](./ci-intro.md) -- [Learn more about the NUnit and MSTest base classes](./test-runners.md) +- [Learn more about the MSTest and NUnit base classes](./test-runners.md)