Skip to content

Commit 993fc6b

Browse files
Initial commit - Playwright C# automation framework setup
0 parents  commit 993fc6b

File tree

11 files changed

+242
-0
lines changed

11 files changed

+242
-0
lines changed

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
bin/
2+
obj/
3+
Reports/
4+
node_modules/
5+
.playwright/

Pages/CartPage.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
using Microsoft.Playwright;
2+
using System.Threading.Tasks;
3+
4+
namespace QA_Automation_Framework_Playwright.Pages
5+
{
6+
public class CartPage
7+
{
8+
private readonly IPage _page;
9+
public CartPage(IPage page) => _page = page;
10+
11+
public async Task GoToCartAsync() => await _page.ClickAsync("#cartur");
12+
13+
public async Task ProceedToCheckoutAsync() =>
14+
await _page.ClickAsync("text=Place Order");
15+
}
16+
}

Pages/CheckoutPage.cs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
using Microsoft.Playwright;
2+
using System.Threading.Tasks;
3+
4+
namespace QA_Automation_Framework_Playwright.Pages
5+
{
6+
public class CheckoutPage
7+
{
8+
private readonly IPage _page;
9+
public CheckoutPage(IPage page) => _page = page;
10+
11+
public async Task FillOrderFormAsync(string name, string country, string city, string card, string month, string year)
12+
{
13+
await _page.FillAsync("#name", name);
14+
await _page.FillAsync("#country", country);
15+
await _page.FillAsync("#city", city);
16+
await _page.FillAsync("#card", card);
17+
await _page.FillAsync("#month", month);
18+
await _page.FillAsync("#year", year);
19+
await _page.ClickAsync("text=Purchase");
20+
}
21+
22+
public async Task<bool> VerifyConfirmationAsync() =>
23+
await _page.IsVisibleAsync("text=Thank you for your purchase!");
24+
}
25+
}

Pages/HomePage.cs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
using Microsoft.Playwright;
2+
using System.Threading.Tasks;
3+
4+
namespace QA_Automation_Framework_Playwright.Pages
5+
{
6+
public class HomePage
7+
{
8+
private readonly IPage _page;
9+
private readonly string _url = "https://demoblaze.com"; // sample e-commerce site
10+
11+
public HomePage(IPage page) => _page = page;
12+
13+
public async Task NavigateAsync() => await _page.GotoAsync(_url);
14+
15+
public async Task ClickProductAsync(string productName)
16+
{
17+
await _page.ClickAsync($"text={productName}");
18+
}
19+
}
20+
}

Pages/ProductPage.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
using Microsoft.Playwright;
2+
using System.Threading.Tasks;
3+
4+
namespace QA_Automation_Framework_Playwright.Pages
5+
{
6+
public class ProductPage
7+
{
8+
private readonly IPage _page;
9+
public ProductPage(IPage page) => _page = page;
10+
11+
public async Task AddToCartAsync()
12+
{
13+
await _page.ClickAsync("text=Add to cart");
14+
await _page.WaitForTimeoutAsync(1000);
15+
await _page.Dialog.AcceptAsync();
16+
}
17+
}
18+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net8.0</TargetFramework>
5+
<ImplicitUsings>enable</ImplicitUsings>
6+
<Nullable>enable</Nullable>
7+
8+
<IsPackable>false</IsPackable>
9+
<IsTestProject>true</IsTestProject>
10+
</PropertyGroup>
11+
12+
<ItemGroup>
13+
<PackageReference Include="coverlet.collector" Version="6.0.0" />
14+
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.0.0" />
15+
<PackageReference Include="Microsoft.Playwright" Version="1.55.0" />
16+
<PackageReference Include="NUnit" Version="3.14.0" />
17+
<PackageReference Include="NUnit.Analyzers" Version="3.9.0" />
18+
<PackageReference Include="NUnit3TestAdapter" Version="5.2.0" />
19+
</ItemGroup>
20+
21+
<ItemGroup>
22+
<Using Include="NUnit.Framework" />
23+
</ItemGroup>
24+
25+
</Project>

README.md

1.16 KB

QA_Automation_Framework_Playwright 🚀

.NET Playwright License

📖 Overview

End-to-end automation framework built with Playwright, C#, and NUnit
for a sample e-commerce checkout flow.

Includes:

  • Page Object Model design
  • HTML reports with ExtentReports
  • Automatic screenshots on failure
  • CI/CD-friendly structure

⚙️ How to Run

dotnet restore
playwright install
dotnet test

Tests/CheckoutTests.cs

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
using NUnit.Framework;
2+
using QA_Automation_Framework_Playwright.Pages;
3+
using QA_Automation_Framework_Playwright.Utilities;
4+
using Microsoft.Playwright;
5+
using AventStack.ExtentReports;
6+
using AventStack.ExtentReports.Reporter;
7+
using System.IO;
8+
using System.Threading.Tasks;
9+
10+
namespace QA_Automation_Framework_Playwright.Tests
11+
{
12+
public class CheckoutTests
13+
{
14+
private IPage _page;
15+
private ExtentReports _extent;
16+
private ExtentTest _test;
17+
18+
[OneTimeSetUp]
19+
public void SetupReporting()
20+
{
21+
var htmlReporter = new ExtentHtmlReporter(Path.Combine(Directory.GetCurrentDirectory(), "Reports", "Report.html"));
22+
_extent = new ExtentReports();
23+
_extent.AttachReporter(htmlReporter);
24+
}
25+
26+
[SetUp]
27+
public async Task Setup()
28+
{
29+
_page = await BrowserFactory.CreatePageAsync();
30+
_test = _extent.CreateTest(TestContext.CurrentContext.Test.Name);
31+
}
32+
33+
[Test]
34+
public async Task ECommerce_Checkout_Flow()
35+
{
36+
var home = new HomePage(_page);
37+
var product = new ProductPage(_page);
38+
var cart = new CartPage(_page);
39+
var checkout = new CheckoutPage(_page);
40+
41+
await home.NavigateAsync();
42+
await home.ClickProductAsync("Samsung galaxy s6");
43+
await product.AddToCartAsync();
44+
await cart.GoToCartAsync();
45+
await cart.ProceedToCheckoutAsync();
46+
await checkout.FillOrderFormAsync("Rustam", "USA", "Tampa", "123456789012", "12", "2025");
47+
48+
Assert.IsTrue(await checkout.VerifyConfirmationAsync(), "Purchase confirmation not visible");
49+
_test.Pass("Checkout flow completed successfully");
50+
}
51+
52+
[TearDown]
53+
public async Task TearDown()
54+
{
55+
if (TestContext.CurrentContext.Result.Outcome.Status == NUnit.Framework.Interfaces.TestStatus.Failed)
56+
{
57+
var screenshot = await ScreenshotHelper.TakeScreenshot(_page);
58+
_test.Fail("Test failed").AddScreenCaptureFromPath(screenshot);
59+
}
60+
await BrowserFactory.CloseAsync();
61+
}
62+
63+
[OneTimeTearDown]
64+
public void FlushReport() => _extent.Flush();
65+
}
66+
}

Utilities/BrowserFactory.cs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
2+
---
3+
4+
## ⚙️ `BrowserFactory.cs`
5+
6+
```csharp
7+
using Microsoft.Playwright;
8+
using System.Threading.Tasks;
9+
10+
namespace QA_Automation_Framework_Playwright.Utilities
11+
{
12+
public static class BrowserFactory
13+
{
14+
private static IPlaywright _playwright;
15+
private static IBrowser _browser;
16+
17+
public static async Task<IPage> CreatePageAsync()
18+
{
19+
_playwright ??= await Playwright.CreateAsync();
20+
_browser ??= await _playwright.Chromium.LaunchAsync(new BrowserTypeLaunchOptions
21+
{
22+
Headless = true
23+
});
24+
25+
var context = await _browser.NewContextAsync();
26+
var page = await context.NewPageAsync();
27+
return page;
28+
}
29+
30+
public static async Task CloseAsync()
31+
{
32+
if (_browser != null)
33+
await _browser.CloseAsync();
34+
}
35+
}
36+
}

Utilities/ScreenshotHelper.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
using Microsoft.Playwright;
2+
using System.IO;
3+
using System.Threading.Tasks;
4+
5+
namespace QA_Automation_Framework_Playwright.Utilities
6+
{
7+
public static class ScreenshotHelper
8+
{
9+
public static async Task<string> TakeScreenshot(IPage page)
10+
{
11+
var dir = Path.Combine(Directory.GetCurrentDirectory(), "Reports", "Screenshots");
12+
Directory.CreateDirectory(dir);
13+
var path = Path.Combine(dir, $"screenshot_{System.DateTime.Now:HHmmss}.png");
14+
await page.ScreenshotAsync(new PageScreenshotOptions { Path = path });
15+
return path;
16+
}
17+
}
18+
}

0 commit comments

Comments
 (0)