Run Playwright-dotnet automation tests on LambdaTest cloud grid
Perform automation testing on 3000+ real desktop and mobile devices online.
using Microsoft.Playwright;
using System.Threading.Tasks;
using Xunit;
namespace BlazorWASMPlaywright.Tests
{
// https://www.meziantou.net/automated-ui-tests-an-asp-net-core-application-with-playwright-and-xunit.htm
public class BlazorWASMPlaywrightTests : IClassFixture<BlazorWebAssemblyWebHostFixture<Program>>
{
private readonly BlazorWebAssemblyWebHostFixture<Program> _server;
public BlazorWASMPlaywrightTests(BlazorWebAssemblyWebHostFixture<Program> server) => _server = server;
[Fact]
public async Task DisplayHomePage()
{
var browser = await GetBrowser();
var page = await browser.NewPageAsync();
await page.GotoAsync(_server.RootUri.AbsoluteUri);
var header = await page.WaitForSelectorAsync("h1");
Assert.Equal("Hello, world!", await header.InnerTextAsync());
await browser.CloseAsync();
}
[Fact]
public async Task Counter()
{
var browser = await GetBrowser();
var page = await browser.NewPageAsync();
await page.GotoAsync(_server.RootUri + "counter", new PageGotoOptions() { WaitUntil = WaitUntilState.NetworkIdle });
await page.ClickAsync("#IncrementBtn");
// Selectors are not only CSS selectors. You can use xpath, css, or text selectors
// By default there is a timeout of 30s. If the selector isn't found after the timeout, an exception is thrown.
// More about selectors: https://playwright.dev/#version=v1.4.2&path=docs%2Fselectors.md
await page.WaitForSelectorAsync("text=Current count: 1");
await browser.CloseAsync();
}
public static async Task<IBrowser> GetBrowser()
{
var playwright = await Playwright.CreateAsync();
var browser = await playwright.Chromium.LaunchAsync(new BrowserTypeLaunchOptions()
{
Headless = false,
SlowMo = 5000
});
return browser;
}
}
}
/*
* MIT License
*
* Copyright (c) Microsoft Corporation.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
using System.Threading.Tasks;
using Microsoft.Playwright.Transport;
using Microsoft.Playwright.Transport.Channels;
namespace Microsoft.Playwright.Core
{
internal class Selectors : ChannelOwnerBase, IChannelOwner<Selectors>, ISelectors
{
private readonly SelectorsChannel _channel;
internal Selectors(IChannelOwner parent, string guid) : base(parent, guid)
{
_channel = new(guid, parent.Connection, this);
}
ChannelBase IChannelOwner.Channel => _channel;
IChannel<Selectors> IChannelOwner<Selectors>.Channel => _channel;
public async Task RegisterAsync(string name, SelectorsRegisterOptions options = default)
{
options ??= new SelectorsRegisterOptions();
var script = ScriptsHelper.EvaluationScript(options?.Script, options?.Path);
await _channel.RegisterAsync(name, script, options?.ContentScript).ConfigureAwait(false);
}
}
}
/*
* MIT License
*
* Copyright (c) Microsoft Corporation.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using Microsoft.Playwright.Transport;
using Microsoft.Playwright.Transport.Channels;
using Microsoft.Playwright.Transport.Protocol;
namespace Microsoft.Playwright.Core
{
[SuppressMessage("Microsoft.Design", "CA1724", Justification = "Playwright is the entrypoint for all languages.")]
internal class PlaywrightImpl : ChannelOwnerBase, IPlaywright, IChannelOwner<PlaywrightImpl>
{
/// <summary>
/// Default timeout.
/// </summary>
public const int DefaultTimeout = 30_000;
private readonly PlaywrightInitializer _initializer;
private readonly PlaywrightChannel _channel;
private readonly Connection _connection;
private readonly Dictionary<string, BrowserNewContextOptions> _devices = new(StringComparer.InvariantCultureIgnoreCase);
internal PlaywrightImpl(IChannelOwner parent, string guid, PlaywrightInitializer initializer)
: base(parent, guid)
{
_connection = parent.Connection;
_initializer = initializer;
_channel = new(guid, parent.Connection, this);
foreach (var entry in initializer.DeviceDescriptors)
{
_devices[entry.Name] = entry.Descriptor;
}
Utils = initializer.Utils;
_initializer.Chromium.Playwright = this;
_initializer.Firefox.Playwright = this;
_initializer.Webkit.Playwright = this;
}
~PlaywrightImpl() => Dispose(false);
Connection IChannelOwner.Connection => _connection;
ChannelBase IChannelOwner.Channel => _channel;
IChannel<PlaywrightImpl> IChannelOwner<PlaywrightImpl>.Channel => _channel;
public IBrowserType Chromium { get => _initializer.Chromium; set => throw new NotSupportedException(); }
public IBrowserType Firefox { get => _initializer.Firefox; set => throw new NotSupportedException(); }
public IBrowserType Webkit { get => _initializer.Webkit; set => throw new NotSupportedException(); }
public ISelectors Selectors => _initializer.Selectors;
public IReadOnlyDictionary<string, BrowserNewContextOptions> Devices => _devices;
internal Connection Connection { get; set; }
internal Browser PreLaunchedBrowser => _initializer.PreLaunchedBrowser;
internal LocalUtils Utils { get; set; }
/// <summary>
/// Gets a <see cref="IBrowserType"/>.
/// </summary>
/// <param name="browserType"><see cref="IBrowserType"/> name. You can get the names from <see cref="global::Microsoft.Playwright.BrowserType"/>.
/// e.g.: <see cref="global::Microsoft.Playwright.BrowserType.Chromium"/>,
/// <see cref="global::Microsoft.Playwright.BrowserType.Firefox"/> or <see cref="global::Microsoft.Playwright.BrowserType.Webkit"/>.
/// </param>
public IBrowserType this[string browserType]
=> browserType?.ToLower() switch
{
global::Microsoft.Playwright.BrowserType.Chromium => Chromium,
global::Microsoft.Playwright.BrowserType.Firefox => Firefox,
global::Microsoft.Playwright.BrowserType.Webkit => Webkit,
_ => null,
};
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool disposing)
{
if (!disposing)
{
return;
}
Connection?.Dispose();
}
}
}
Accelerate Your Automation Test Cycles With LambdaTest
Leverage LambdaTest’s cloud-based platform to execute your automation tests in parallel and trim down your test execution time significantly. Your first 100 automation testing minutes are on us.