如何使用specflow和Playwright测试不同的浏览器(交叉浏览)

问题描述 投票:0回答:2

我是 Playwright 和 specflow 的新手,我想知道在所有浏览器(chromium、firefox、webkit)上测试场景的最佳方法是什么。 当前的项目使用了Selenium,但现在我们想使用playwright来实现这一点。 您知道如何有效地实现这一目标吗? 谢谢!

我尝试在场景中使用标签 @chromium @firefox @webkit 并创建一个钩子类:

using TechTalk.SpecFlow;
using System;
using Microsoft.Playwright;
using System.Linq;
using BoDi;
using NLog.Targets;

namespace mynamespace.Steps
{
    [Binding]
    public class Hooks : IDisposable
    {
        private readonly IObjectContainer _container;
        private readonly IPlaywright _playwright;

        public Hooks(IObjectContainer container, IPlaywright playwright)
        {
            this._container = container;
            this._playwright = playwright;
        }

        [BeforeScenario(Order = 0)]
        public void InitializePlaywrightContext()
        {
            // Get the browser types from the command-line parameters
            var browserTypes = GetBrowserTypesFromCommandLine();
            var iBrowserTypes = browserTypes.Cast<IBrowserType>().ToArray();

            // Initialize the Playwright context and register it in the ObjectContainer
            var playwrightContext = new PlaywrightContext(iBrowserTypes);
            _container.RegisterInstanceAs(playwrightContext);
        }

        private IBrowserType[] GetBrowserTypesFromCommandLine()
        {
            var browserArg = Environment.GetEnvironmentVariable("browser");

            if (string.IsNullOrEmpty(browserArg))
            {
                var chromium = BrowserType.Chromium.ToArray();
                // If no browser argument is specified, default to Chromium
                return new IBrowserType[] { _playwright.Chromium };
            }
            else
            {
                // Split the browserArg by commas to get multiple browsers
                var browserNames = browserArg.ToLower().Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                // Map the browser names to corresponding BrowserType
                IBrowserType[] browserTypes = browserNames.Select(browserName =>
                {
                    
                    return browserName switch
                    {
                        "chromium" => _playwright.Chromium,
                        "firefox" => _playwright.Firefox,
                        "webkit" => _playwright.Webkit,
                        _ => _playwright.Chromium,// If an invalid browser name is specified, default to Chromium
                    };
                }).ToArray();

                return browserTypes;
            }
        }
        public void Dispose()
        {
            _container?.Dispose();
        }
    }

}

然后创建一个剧作家上下文:

using Microsoft.Playwright;
using BoDi;
using System.Collections.Generic;
using System;
using System.Threading.Tasks;

public class PlaywrightContext
{
    private readonly IBrowserType[] browserTypes;
    private readonly IPage[] pages;
    public IBrowser[] Browsers { get; private set; }
    public IPage[] Pages { get; private set; }

    public PlaywrightContext(IObjectContainer container, IBrowserType[] browserTypes)
    {
        this.browserTypes = browserTypes;
        Initialize(container);
    }

    private void Initialize(IObjectContainer container)
    {
        Browsers = new IBrowser[browserTypes.Length];
        Pages = new IPage[browserTypes.Length];

        for (int i = 0; i < browserTypes.Length; i++)
        {
            Browsers[i] = browserTypes[i].LaunchAsync().GetAwaiter().GetResult();
            Pages[i] = Browsers[i].NewPageAsync().GetAwaiter().GetResult();
            container.RegisterInstanceAs(Browsers[i]);
            container.RegisterInstanceAs(Pages[i]);
        }
    }

    public IBrowser GetBrowserForBrand(string branding)
    {
        // Implement logic to return the corresponding browser based on branding
        // For example:
        if (branding == "Chrome")
        {
            return Browsers[0]; // Assuming Chrome is the first browser in the array
        }
        else if (branding == "Firefox")
        {
            return Browsers[1]; // Assuming Firefox is the second browser in the array
        }
        else if (branding == "Webkit")
        {
            return Browsers[2]; // Assuming Webkit is the third browser in the array
        }
        else
        {
            throw new ArgumentException($"Invalid branding: {branding}");
        }
    }

    public async ValueTask DisposeAsync()
    {
        foreach (var browser in Browsers)
        {
            await browser?.CloseAsync();
        }
    }
}

但不知道如何在我的步骤课中使用它:

namespace mynamespace.Steps
{
    [Binding]
    public sealed class TransactionStepsPlaywright
    {
        private readonly ScenarioContext _scenarioContext;
        private readonly ITransactionService _transactionService;
        private readonly ApiSettings _apiSettings;
        private readonly ILoggingService _loggingService;
        private readonly int _maxRetries = 3;
        private readonly INavigationPane _navigationPane;
        private readonly IOtpService _otpService;
        private readonly IObjectContainer _container;
        private readonly PlaywrightContext _playwrightContext;
        private readonly IPlaywright _playwright; // Add IPlaywright dependency

        public TransactionStepsPlaywright(ScenarioContext scenarioContext, PlaywrightContext playwrightContext, IObjectContainer container, ILoggingService loggingService, ITransactionService transactionService, IOtpService otpService, IPlaywright playwright, IOptions<ApiSettings> apiSettingsOption, INavigationPane navigationPane) // Add IPlaywright here
        {
            _scenarioContext = scenarioContext;
            _transactionService = transactionService;
            _playwright = playwright; // Use IPlaywright here
            _apiSettings = apiSettingsOption.Value;
            _loggingService = loggingService;
            _navigationPane = navigationPane;
            _otpService = otpService;
            _container = container;
            _playwrightContext = playwrightContext;
        }

        [Given(@"pw I open the login page for (.*)")]
        public void GivenIOpenTheLoginPageFor(string branding)
        {
            try
            {
                var url = _apiSettings.EndPoints.FirstOrDefault(
                    ep => string.Compare(ep.Name, branding, StringComparison.InvariantCultureIgnoreCase) == 0
                ).Url;

                var browser = _playwrightContext.GetBrowserForBrand(branding); // Get the corresponding browser for the given branding
                var page = browser.NewPageAsync().GetAwaiter().GetResult(); // Create a new page for the browser

                page.GotoAsync(url).GetAwaiter().GetResult();
                Console.WriteLine($"Opened the login page for branding: {branding} in {browser.Name}.");
            }
            catch (Exception)
            {
                throw new Exception($"Could not navigate to login page for branding: {branding}.");
            }
        }
c# cross-browser bdd playwright specflow
2个回答
0
投票

我对PlayWright不熟悉,但根据您提供的内容,它根据环境变量初始化浏览器。设置名为“browser”的环境变量,值为“chromium,firefox,webkit”,并在“Given”中使用它作为“pw我打开Chrome的登录页面”或“pw我打开Firefox的登录页面”。

初始化默认为

chromium
,您可以使用
Given
测试您的
"pw I open the login page for Chrome"
,看看它是否有效。


0
投票

我使用以下代码在不同浏览器中进行测试:

namespace PlayWrightSpecFlow.Drivers
{
    public class Driver : IDisposable
    {

    private readonly Task<IPage> _page;
    
    private IBrowser? _browser;
    public Driver()
    {
        _page = InitializePlaywright();
    }

    public IPage Page => _page.Result;

    // creating/initializing playwright
    private async Task<IPage> InitializePlaywright()
    {
        //Playwright >>> it will start downaloding things for us for automation.
        var playwright = await Playwright.CreateAsync();

        //create browser instance
        _browser = await playwright.Chromium.LaunchAsync(new BrowserTypeLaunchOptions
        {
            Headless = false,
           // SlowMo = 1000,
           Timeout = 50000,
           Channel = "chrome"


        });
        

        //create page instance
        return await _browser.NewPageAsync();
    }
    public void Dispose() => _browser?.CloseAsync();


}

}

_browser = wait playwright.Chromium.LaunchAsync >>> 它将启动 Chromium 引擎。如果您选择频道为 Chrome,它将启动 Chrome 浏览器,如果您选择频道为 MS Edge(Edge 使用 chromium 浏览器引擎),它将启动 MS Edge 浏览器。

如果要打开 Firefox 或 webkit,请将 Chromium 替换为 Firefox,无需添加通道。

© www.soinside.com 2019 - 2024. All rights reserved.