-
Notifications
You must be signed in to change notification settings - Fork 252
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Feature]: Load Playwright settings programmatically as an alternative to a .runsettings
file
#3081
Comments
As an alternative to using a .runsettings XML file. Fixes microsoft#3081
As an alternative to using a .runsettings XML file. Fixes microsoft#3081
As an alternative to using a .runsettings XML file. Fixes microsoft#3081
We intentionally had these settings configured on a global level before - this would require us to diverge from what we do in Node.js or Python. Usually for end-to-end tests, you write a test once and run them on all the browsers. For that you run |
Hi @0xced, if it helps with what you need, I usually prefer to have a JSON configuration file and define my browser options in there under different profiles, then I just deserialise as needed and pass that object to the browser on initialisation. The profile is selected by name by an environment variable of sorts, so it can be dynamically set, e.g. .runsettings, CLI command argument, or pipeline variable. Some of the reasons for which I prefer this method are that 1) it keeps the config out of the code, which is what I believe that the official .runsettings approach is aiming for, but 2) is more powerful, flexible, reusable, and transparent than .runsetting config. |
As an alternative to using a .runsettings XML file. Fixes microsoft#3081
That's one way to do it, I personally prefer to control how tests are run with C# code rather than in yaml or shell scripts.
For example, to test on older systems where the newest versions of Chromium and WebKit are not supported anymore. But again, the point is to control all of this from C# instead of yaml or shell scripts. If #3082 is not accepted, it's still possible to load the settings programmatically without being part of Playwright test adapter project. It's just much uglier because one has to go through the hoops of creating an using System;
using System.Linq;
using System.Text.Json;
using System.Xml;
using System.Xml.Linq;
using Microsoft.Playwright;
using Microsoft.Playwright.TestAdapter;
namespace SampleCode;
public class PlaywrightSettings
{
public PlaywrightBrowser Browser { get; set; } = PlaywrightBrowser.Chromium;
public BrowserTypeLaunchOptions? LaunchOptions { get; set; }
public TimeSpan? ExpectTimeout { get; set; }
public void Install()
{
using var reader = CreateXmlReader();
new PlaywrightSettingsProvider().Load(reader);
}
private XmlReader CreateXmlReader()
{
var playwright = new XElement("Playwright", new XElement("BrowserName", Browser));
if (LaunchOptions != null)
{
playwright.Add(CreateLaunchOptions(LaunchOptions));
}
if (ExpectTimeout != null)
{
playwright.Add(new XElement(nameof(ExpectTimeout), ExpectTimeout.Value.TotalMilliseconds));
}
return playwright.CreateReader();
}
private static XElement CreateLaunchOptions(BrowserTypeLaunchOptions options)
{
var launchOptions = new XElement(nameof(LaunchOptions));
if (options.Args != null) launchOptions.Add(new XElement(nameof(options.Args)), JsonSerializer.Serialize(options.Args));
if (options.Channel != null) launchOptions.Add(new XElement(nameof(options.Channel)), options.Channel);
if (options.ChromiumSandbox != null) launchOptions.Add(new XElement(nameof(options.ChromiumSandbox)), options.ChromiumSandbox);
#pragma warning disable CS0612 // Type or member is obsolete
if (options.Devtools != null) launchOptions.Add(new XElement(nameof(options.Devtools)), options.Devtools);
#pragma warning restore CS0612 // Type or member is obsolete
if (options.DownloadsPath != null) launchOptions.Add(new XElement(nameof(options.DownloadsPath)), options.DownloadsPath);
if (options.Env != null) launchOptions.Add(new XElement(nameof(options.Env)), JsonSerializer.Serialize(options.Env.ToDictionary(x => x.Key)));
if (options.ExecutablePath != null) launchOptions.Add(new XElement(nameof(options.ExecutablePath)), options.ExecutablePath);
if (options.FirefoxUserPrefs != null) launchOptions.Add(new XElement(nameof(options.FirefoxUserPrefs)), JsonSerializer.Serialize(options.FirefoxUserPrefs.ToDictionary(x => x.Key)));
if (options.HandleSIGHUP != null) launchOptions.Add(new XElement(nameof(options.HandleSIGHUP)), options.HandleSIGHUP);
if (options.HandleSIGINT != null) launchOptions.Add(new XElement(nameof(options.HandleSIGINT)), options.HandleSIGINT);
if (options.HandleSIGTERM != null) launchOptions.Add(new XElement(nameof(options.HandleSIGTERM)), options.HandleSIGTERM);
if (options.Headless != null) launchOptions.Add(new XElement(nameof(options.Headless)), options.Headless);
if (options.IgnoreAllDefaultArgs != null) launchOptions.Add(new XElement(nameof(options.IgnoreAllDefaultArgs)), options.IgnoreAllDefaultArgs);
if (options.IgnoreDefaultArgs != null) launchOptions.Add(new XElement(nameof(options.IgnoreDefaultArgs)), options.IgnoreDefaultArgs);
if (options.Proxy?.Server != null) launchOptions.Add(new XElement(nameof(options.Proxy)), CreateProxy(options.Proxy));
if (options.SlowMo != null) launchOptions.Add(new XElement(nameof(options.SlowMo)), options.SlowMo);
if (options.Timeout != null) launchOptions.Add(new XElement(nameof(options.Timeout)), options.Timeout);
if (options.TracesDir != null) launchOptions.Add(new XElement(nameof(options.TracesDir)), options.TracesDir);
return launchOptions;
}
private static XElement CreateProxy(Proxy value)
{
var proxy = new XElement(nameof(Proxy), new XAttribute(nameof(value.Server), value.Server));
if (value.Bypass != null) proxy.Add(new XElement(nameof(value.Bypass), value.Bypass));
if (value.Username != null) proxy.Add(new XElement(nameof(value.Username), value.Username));
if (value.Password != null) proxy.Add(new XElement(nameof(value.Password), value.Password));
return proxy;
}
} |
🚀 Feature Request
Currently, setting the
BrowserTypeLaunchOptions
when running tests with theMicrosoft.Playwright.MSTest
,Microsoft.Playwright.NUnit
orMicrosoft.Playwright.Xunit
pacakge is controlled through the .runsettings configuration file.It would be nice to be able to control the launch options programmatically, just like
BrowserNewContextOptions
can be controlled programmatically by overriding theContextOptions()
method.Example
This example is given with Xunit but would work the same with MSTest or NUnit.
Motivation
Controlling options programatically opens up new possibilities that are not achievable with a
.runsettings
file. For example, one could decide to run tests on Firefox based on some runtime conditions or change the value of theTimeout
based on what hardware the tests are running on. This would give a lot of power to Playwright users.Also, having a new
PlaywrightSettings
type is great for discoverability. Typing properties with autocompletion support from your IDE is a much better experience than writing XML elements in a.runsettings
file without any autocompletion.Finally,
.runsettings
support in Rider is pretty broken, I was not able to get theMicrosoft.VisualStudio.TestPlatform.ObjectModel.Adapter.ISettingsProvider.Load
method to be called, rendring Playwright.runsettings
unusable with Rider. See alsoTestCaseFilter
in.runsettings
ignored.The text was updated successfully, but these errors were encountered: