QA Fortify
QA Fortify

Reputation: 49

Good PageObject Example for PlayWright-Sharp don't seem to exist

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

Answers (3)

QA Fortify
QA Fortify

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

Xen0byte
Xen0byte

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

Anže Vodovnik
Anže Vodovnik

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

Related Questions