Reputation: 49
Im looking for a good PageObject example::
this is a sample of what I'm trying... but the when I start the test from another file... the InstallAsync() starts the test instead and of course fails because the ipage is null
why isn't the ipage object returned?
public async Task<IPage> LaunchChrome()
{
await Playwright.InstallAsync();
using var playwright = await Playwright.CreateAsync();
await using var browser = await playwright.Webkit.LaunchAsync(headless: false);
var page = await browser.NewPageAsync();
return page;
}
Upvotes: 1
Views: 4428
Reputation: 49
This is a simple example of what I did..
BaseFile
namespace UsingPlayWriteSharp.PageObjects
{
[TestClass]
public abstract class WebBaseClient : IDisposable
{
public static string BaseURL { get; set; }
private static string _BaseURL = string.Empty;
private static string BrowserType { get; set; }
private static string _BrowserType = string.Empty;
//
public IPlaywright iplaywright;
public IBrowser ibrowser;
public IPage ipage;
public IBrowserContext icontext;
protected WebBaseClient()
{
BaseURL = _BaseURL;
BrowserType = _BrowserType;
}
[AssemblyInitialize]
public static void AssemblyTestInitialize(TestContext TestContext)
{
_BrowserType = TestContext.Properties["browser"].ToString();
_BaseURL = TestContext.Properties["appURL"].ToString();
}
[TestInitialize]
public virtual void TestInitialize()
{
InitializeWebDriver(BrowserType);
}
/// <summary>
/// Used to Select Browser and Device
/// </summary>
/// <param name="browsertype"></param>
protected void InitializeWebDriver(string browsertype)
{
switch (browsertype.ToLower())
{
case "firefox":
if (ibrowser == null)
{
ibrowser = Task.Run(() => GetBrowserFireFoxAsync()).Result;
};
break;
case "firefoxheadless":
if (ibrowser == null)
{
ibrowser = Task.Run(() => GetBrowserFireFoxAsync(true)).Result;
};
break;
case "chrome":
if (ibrowser == null)
{
ibrowser = Task.Run(() => GetBrowserChromeAsync()).Result;
};
break;
case "chromeheadless":
if (ibrowser == null)
{
ibrowser = Task.Run(() => GetBrowserChromeAsync(true)).Result;
};
break;
case "safari":
if (ibrowser == null)
{
ibrowser = Task.Run(() => GetBrowserSafariAsync()).Result;
};
break;
case "ipad":
if (icontext == null)
{
icontext = Task.Run(() => GetBrowseriPadPro()).Result;
};
break;
case "iphone11":
if (icontext == null)
{
icontext = Task.Run(() => GetBrowseriPhonePro()).Result;
};
break;
default:
throw new Exception("Invalid value for parameter named browser in the file *.runsettings. \r\n ");
}
}
/// <summary>
/// Select iPad headless or visible - default is false for testing
/// </summary>
/// <param name="headless"></param>
/// <returns></returns>
private async Task<IBrowserContext> GetBrowseriPadPro(bool headless = false)
{
IBrowserContext browserContext;
await Playwright.InstallAsync();
var playwright = await Playwright.CreateAsync();
ibrowser = await playwright.Webkit.LaunchAsync(headless);
var browserContextOptions = playwright.Devices["iPad Mini"].ToBrowserContextOptions();
browserContextOptions.AcceptDownloads = true;
browserContextOptions.IsMobile = true;
browserContextOptions.Locale = "en-US";
browserContext = await ibrowser.NewContextAsync(browserContextOptions);
return browserContext;
}
/// <summary>
/// Select iPhone headless or visible - default is false for testing
/// </summary>
/// <param name="headless"></param>
/// <returns></returns>
private async Task<IBrowserContext> GetBrowseriPhonePro(bool headless = false)
{
IBrowserContext browserContext;
await Playwright.InstallAsync();
var playwright = await Playwright.CreateAsync();
ibrowser = await playwright.Webkit.LaunchAsync(headless);
var browserContextOptions = playwright.Devices["iPhone 11 Pro"].ToBrowserContextOptions();
browserContextOptions.AcceptDownloads = true;
browserContextOptions.IsMobile = true;
browserContextOptions.Locale = "en-US";
browserContext = await ibrowser.NewContextAsync(browserContextOptions);
return browserContext;
}
/// <summary>
/// Select Safari headless or visible - default is false for testing
/// </summary>
/// <param name="headless"></param>
/// <returns></returns>
private async Task<IBrowser> GetBrowserSafariAsync(bool headless = false)
{
await Playwright.InstallAsync();
var playwright = await Playwright.CreateAsync();
if (headless)
{
ibrowser = await playwright.Webkit.LaunchAsync(headless: headless);
}
else
{
ibrowser = await playwright.Webkit.LaunchAsync(headless: headless);
}
return ibrowser;
}
/// <summary>
/// Select Chrome headless or visible - default is false for testing
/// </summary>
/// <param name="headless"></param>
/// <returns></returns>
private async Task<IBrowser> GetBrowserChromeAsync(bool headless = false)
{
IChromiumBrowser chrome;
await Playwright.InstallAsync();
var playwright = await Playwright.CreateAsync();
if (headless)
{
chrome = await playwright.Chromium.LaunchAsync(headless: headless);
}
else
{
chrome = await playwright.Chromium.LaunchAsync(headless: headless);
}
return chrome;
}
/// <summary>
/// Select FireFox headless or visible - default is false for testing
/// </summary>
/// <param name="headless"></param>
/// <returns></returns>
private async Task<IBrowser> GetBrowserFireFoxAsync(bool headless = false)
{
await Playwright.InstallAsync();
var playwright = await Playwright.CreateAsync();
if (headless)
{
ibrowser = await playwright.Firefox.LaunchAsync(headless: headless);
}
else
{
ibrowser = await playwright.Firefox.LaunchAsync(headless: headless);
}
return ibrowser;
}
public void Dispose()
{
iplaywright?.Dispose();
ipage?.CloseAsync();
}
}
}
Page object
namespace UsingPlayWriteSharp.PageObjects {
public class LoginPageModel
{
private readonly string usrname = "input[id="UserName"]";
private readonly string loginButton = "#Login-Link";
private readonly string nextButton = "#next";
private IPage page;
public LoginPageModel(IPage ipage)
{
page = ipage;
}
public async Task ClickLoginButton()
{
await page.ClickAsync(loginButton);
}
public async Task EnterUserName(string username)
{
await page.TypeAsync(usrname, username);
}
public async Task ClickNextButton()
{
await page.ClickAsync(nextButton);
}
}
}
Sample Test
namespace UsingPlayWriteSharp {
[TestClass]
public class DemoTest : WebBaseClient
{
private LoginPageModel login;
private PlaywrightSharp.IBrowserContext browserContext;
string username = "[email protected]";
[TestMethod]
public async Task SimpleTestAsync()
{
await ipage.GoToAsync(BaseURL);
login = new LoginPageModel(ipage);
await login.ClickLoginButton();
await login.EnterUserName(username);
await login.ClickNextButton();
}
[TestInitialize]
public async Task TestInitializer()
{
browserContext = await ibrowser.NewContextAsync();
ipage = await browserContext.NewPageAsync();
}
}
}
Upvotes: 1
Reputation: 109
I've just started fully migrating my framework from Selenium to Playwright and, for the time being, I'm doing something along these lines:
using PlaywrightSharp;
using System.Threading.Tasks;
namespace Z34.PageTypes
{
public class LoginPage
{
private readonly IPage Self;
public LoginPage(IPage page) => Self = page;
private string UsernameInput => "#username";
private string PasswordInput => "#password";
private string LoginButton => "text='Sign In'";
private async Task ClickLoginButton() => await Self.ClickAsync(LoginButton);
public async Task LogIn(string user, string pass)
{
await Self.TypeAsync(UsernameInput, user);
await Self.TypeAsync(PasswordInput, pass);
await ClickLoginButton();
}
}
}
I suppose a different approach could be:
using PlaywrightSharp;
using System.Threading.Tasks;
namespace Z34.PageTypes
{
public class LoginPage
{
private readonly IPage Self;
public LoginPage(IPage page) => Self = page;
private async Task<IElementHandle> UsernameInput() => Self.QuerySelectorAsync("#username");
private async Task<IElementHandle> PasswordInput() => Self.QuerySelectorAsync("#password");
private async Task<IElementHandle> LoginButton() => Self.QuerySelectorAsync("text='Sign In'");
public async Task LogIn(string user, string pass)
{
await UsernameInput().TypeAsync(user);
await PasswordInput().TypeAsync(pass);
await LoginButton().ClickAsync();
}
}
}
I will look into ways to improve this in the future, when the official documentation comes out but, for now, this works for me.
Upvotes: 1
Reputation: 2345
This looks like a "duplicate" to a question we received in the Playwright sharp repository.
For the sake of completeness, I'll add the same code here. I'm assuming this talks about running Playwright Sharp in a Unit Test. Specifically, I'm using Xunit for this. We use the same approach in Playwright Sharp tests themselves.
First, you define a a Fixture
and a Collection
if you want to reuse the Browser
object across your tests. There's more written about that here.
public class BrowserTestFixture : IAsyncLifetime
{
public IPlaywright PlaywrightContext { get; private set; }
public IChromiumBrowser Browser { get; private set; }
public async Task InitializeAsync()
{
this.PlaywrightContext = await Playwright.CreateAsync();
this.Browser = await this.PlaywrightContext.Chromium.LaunchAsync(headless: false);
}
public async Task DisposeAsync()
{
PlaywrightContext?.Dispose();
}
}
[CollectionDefinition("Browser Collection")]
public class BrowserCollection : ICollectionFixture<BrowserTestFixture>
{
// This class has no code, and is never created. Its purpose is simply
// to be the place to apply [CollectionDefinition] and all the
// ICollectionFixture<> interfaces.
}
At this point, your tests can reuse these objects by including that Fixture
reference in the constructor. The example I used is here:
public class UnitTest1 : IClassFixture<BrowserTestFixture>
{
private readonly BrowserTestFixture browserTestFixture;
public UnitTest1(BrowserTestFixture browserTestFixture)
{
this.browserTestFixture = browserTestFixture;
}
[Fact]
public async Task HeadlineIsThere()
{
var page = await browserTestFixture.Browser.NewPageAsync();
await page.GoToAsync("https://www.github.com");
var content = await page.GetTextContentAsync("h1");
Assert.Equal("...", content);
}
[Fact]
public async Task CookieConsentDialogIsShownAndDissmisable()
{
var page = await browserTestFixture.Browser.NewPageAsync();
await page.GoToAsync("https://www.github.com");
var cookieDialogContents = await page.GetTextContentAsync(".cc-message");
Assert.True(!string.IsNullOrEmpty(cookieDialogContents));
await page.ClickAsync("[aria-label='dismiss cookie message']");
// ...
}
}
Now, I explicitly want to create a new IPage
object every single time, but if you are adamant about reusing/sharing it, you can adapt the example, i.e. providing a PageTestFixture
.
Upvotes: 1