1

我正在寻找一个好的 PageObject 示例::

这是我正在尝试的示例...但是当我从另一个文件开始测试时... InstallAsync() 开始测试,当然会失败,因为 ipage 为空

为什么没有返回 ipage 对象?

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;
        }
4

3 回答 3

1

这看起来像是我们在剧作家敏锐存储库中收到的一个问题的“重复”。

为了完整起见,我将在此处添加相同的代码。我假设这是关于在单元测试中运行 Playwright Sharp 的。具体来说,我为此使用 Xunit。我们在 Playwright Sharp 测试中使用相同的方法。

首先,如果要在测试中重用对象,则定义 aaFixture和 a 。这里有更多关于它的文章。CollectionBrowser

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.
}

此时,您的测试可以通过Fixture在构造函数中包含该引用来重用这些对象。我使用的示例在这里:

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']");
        // ...
    }
}

现在,我明确希望IPage每次都创建一个新对象,但如果您坚持重复使用/共享它,您可以调整示例,即提供一个PageTestFixture.

于 2021-01-19T16:06:14.553 回答
1

这是我所做的一个简单的例子..

基本文件

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();
    }
}
}

页面对象

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);
    }
}
}

样品测试

namespace UsingPlayWriteSharp {
[TestClass]
public class DemoTest : WebBaseClient
{
private LoginPageModel login;
  private PlaywrightSharp.IBrowserContext browserContext;
string username = "Aaron_Mraz@demo.com";

    [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();
        }
}
}
于 2021-02-18T03:00:01.380 回答
1

我刚刚开始将我的框架从 Selenium 完全迁移到 Playwright,目前,我正在做一些事情:

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();
        }
    }
}

我想另一种方法可能是:

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();
        }
    }
}

将来,当官方文档发布时,我将研究改进这一点的方法,但目前,这对我有用。

于 2021-01-18T17:13:16.827 回答