Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ on:
branches:
- main
- release-*
env:
DEBUG: pw:dotnet

jobs:
test-net5:
Expand Down
2 changes: 1 addition & 1 deletion src/Common/Version.props
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<PropertyGroup>
<AssemblyVersion>1.17.1</AssemblyVersion>
<PackageVersion>$(AssemblyVersion)-next-1</PackageVersion>
<DriverVersion>1.18.0-alpha-1638917105000</DriverVersion>
<DriverVersion>1.18.0-beta-1642018269000</DriverVersion>
<ReleaseVersion>$(AssemblyVersion)</ReleaseVersion>
<FileVersion>$(AssemblyVersion)</FileVersion>
<NoDefaultExcludes>true</NoDefaultExcludes>
Expand Down
3 changes: 2 additions & 1 deletion src/Playwright.Tests/BrowserTypeConnectTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -452,7 +452,7 @@ public async Task ShouldRecordContextTraces()
var context = await browser.NewContextAsync();
var page = await context.NewPageAsync();

await context.Tracing.StartAsync();
await context.Tracing.StartAsync(new() { Sources = true });
await page.GotoAsync(Server.EmptyPage);
await page.SetContentAsync("<button>Click</button>");
await page.ClickAsync("button");
Expand All @@ -464,6 +464,7 @@ public async Task ShouldRecordContextTraces()
ZipFile.ExtractToDirectory(tracePath, tempDirectory.Path);
Assert.That(tempDirectory.Path + "/trace.trace", Does.Exist);
Assert.That(tempDirectory.Path + "/trace.network", Does.Exist);
Assert.AreEqual(1, Directory.GetFiles(Path.Join(tempDirectory.Path, "resources"), "*.txt").Length);
}

private class RemoteServer
Expand Down
12 changes: 6 additions & 6 deletions src/Playwright.Tests/Locator/LocatorQueryTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -87,42 +87,42 @@ public async Task ShouldThrowDueToStrictness2()
public async Task ShouldFilterByText()
{
await Page.SetContentAsync("<div>Foobar</div><div>Bar</div>");
StringAssert.Contains(await Page.Locator("div").WithText("Foo").TextContentAsync(), "Foobar");
StringAssert.Contains(await Page.Locator("div", new() { HasTextString = "Foo" }).TextContentAsync(), "Foobar");
}

[PlaywrightTest("locator-query.spec.ts", "should filter by text 2")]
public async Task ShouldFilterByText2()
{
await Page.SetContentAsync("<div>foo <span>hello world</span> bar</div>");
StringAssert.Contains(await Page.Locator("div").WithText("hello world").TextContentAsync(), "foo hello world bar");
StringAssert.Contains(await Page.Locator("div", new() { HasTextString = "hello world" }).TextContentAsync(), "foo hello world bar");
}

[PlaywrightTest("locator-query.spec.ts", "should filter by regex")]
public async Task ShouldFilterByRegex()
{
await Page.SetContentAsync("<div>Foobar</div><div>Bar</div>");
StringAssert.Contains(await Page.Locator("div").WithText(new Regex("Foo.*")).InnerTextAsync(), "Foobar");
StringAssert.Contains(await Page.Locator("div", new() { HasTextRegex = new Regex("Foo.*") }).InnerTextAsync(), "Foobar");
}

[PlaywrightTest("locator-query.spec.ts", "should filter by text with quotes")]
public async Task ShouldFilterByTextWithQuotes()
{
await Page.SetContentAsync("<div>Hello \"world\"</div><div>Hello world</div>");
StringAssert.Contains(await Page.Locator("div").WithText("Hello \"world\"").InnerTextAsync(), "Hello \"world\"");
StringAssert.Contains(await Page.Locator("div", new() { HasTextString = "Hello \"world\"" }).InnerTextAsync(), "Hello \"world\"");
}

[PlaywrightTest("locator-query.spec.ts", "should filter by regex with quotes")]
public async Task ShouldFilterByRegexWithQuotes()
{
await Page.SetContentAsync("<div>Hello \"world\"</div><div>Hello world</div>");
StringAssert.Contains(await Page.Locator("div").WithText(new Regex("Hello \"world\"")).InnerTextAsync(), "Hello \"world\"");
StringAssert.Contains(await Page.Locator("div", new() { HasTextRegex = new Regex("Hello \"world\"") }).InnerTextAsync(), "Hello \"world\"");
}

[PlaywrightTest("locator-query.spec.ts", "should filter by regex and regexp flags")]
public async Task ShouldFilterByRegexandRegexpFlags()
{
await Page.SetContentAsync("<div>Hello \"world\"</div><div>Hello world</div>");
StringAssert.Contains(await Page.Locator("div").WithText(new Regex("hElLo \"wOrld\"", RegexOptions.IgnoreCase)).InnerTextAsync(), "Hello \"world\"");
StringAssert.Contains(await Page.Locator("div", new() { HasTextRegex = new Regex("hElLo \"wOrld\"", RegexOptions.IgnoreCase) }).InnerTextAsync(), "Hello \"world\"");
}
}
}
5 changes: 3 additions & 2 deletions src/Playwright.Tests/PageWaitForRequestTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,12 @@ public Task ShouldRespectTimeout()
}

[PlaywrightTest("page-wait-for-request.spec.ts", "should respect default timeout")]
public Task ShouldRespectDefaultTimeout()
public async Task ShouldRespectDefaultTimeout()
{
Page.SetDefaultTimeout(1);
return PlaywrightAssert.ThrowsAsync<TimeoutException>(
var exception = await PlaywrightAssert.ThrowsAsync<TimeoutException>(
() => Page.WaitForRequestAsync(_ => false));
StringAssert.Contains(exception.Message, "Timeout 1ms exceeded while waiting for event \"Request\"");
}

[PlaywrightTest("page-wait-for-request.spec.ts", "should work with no timeout")]
Expand Down
2 changes: 1 addition & 1 deletion src/Playwright.Tests/TapTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ await Page.SetContentAsync(
await Page.TapAsync("#b", new() { Trial = true });

string[] result = await handle.JsonValueAsync<string[]>();
Assert.AreEqual(result, new string[] { });
Assert.AreEqual(result, new string[] { "pointerover", "pointerenter", "pointerout", "pointerleave" });
}

[PlaywrightTest("tap.spec.ts", "should not send mouse events touchstart is canceled")]
Expand Down
86 changes: 50 additions & 36 deletions src/Playwright.Tests/TracingTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,11 @@
*/

using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
Expand Down Expand Up @@ -58,7 +60,7 @@ await Context.Tracing.StartAsync(new()
var tracePath = Path.Combine(tmp.Path, "trace.zip");
await Context.Tracing.StopAsync(new() { Path = tracePath });

var events = ParseTrace(tracePath);
var (events, resources) = ParseTrace(tracePath);
CollectionAssert.IsNotEmpty(events);

Assert.AreEqual("context-options", events[0].Type);
Expand All @@ -73,25 +75,6 @@ await Context.Tracing.StartAsync(new()
Assert.GreaterOrEqual(events.Where(x => x.Type == "screencast-frame").Count(), 1);
}

[PlaywrightTest("tracing.spec.ts", "should exclude internal pages")]
[Ignore("Fails due to https://github.com/microsoft/playwright/issues/6743")]
public async Task ShouldExcludeInternalPages()
{
var page = await Context.NewPageAsync();
await page.GotoAsync(Server.EmptyPage);

await Context.Tracing.StartAsync();
await Context.StorageStateAsync();
await page.CloseAsync();

using var tmp = new TempDirectory();
var tracePath = Path.Combine(tmp.Path, "trace.zip");
await Context.Tracing.StopAsync(new() { Path = tracePath });
var trace = ParseTrace(tracePath);

Assert.AreEqual(1, trace.Where(x => x.Metadata != null).Select(x => x.Metadata.PageId).Distinct().Count());
}

[PlaywrightTest("tracing.spec.ts", "should collect two traces")]
public async Task ShouldCollectTwoTraces()
{
Expand All @@ -112,7 +95,7 @@ public async Task ShouldCollectTwoTraces()
await Context.Tracing.StopAsync(new() { Path = trace2Path });

{
var events = ParseTrace(trace1Path);
var (events, resources) = ParseTrace(trace1Path);
Assert.AreEqual("context-options", events[0].Type);
Assert.GreaterOrEqual(events.Where(x => x.ApiName == "frame.goto").Count(), 1);
Assert.GreaterOrEqual(events.Where(x => x.ApiName == "frame.setContent").Count(), 1);
Expand All @@ -122,7 +105,7 @@ public async Task ShouldCollectTwoTraces()
}

{
var events = ParseTrace(trace2Path);
var (events, resources) = ParseTrace(trace2Path);
Assert.AreEqual("context-options", events[0].Type);
Assert.AreEqual(0, events.Where(x => x.ApiName == "frame.goto").Count());
Assert.AreEqual(0, events.Where(x => x.ApiName == "frame.setContent").Count());
Expand All @@ -133,28 +116,59 @@ public async Task ShouldCollectTwoTraces()

}

private static IReadOnlyList<TraceEventEntry> ParseTrace(string path)
[PlaywrightTest("tracing.spec.ts", "should collect sources")]
public async Task ShouldCollectSources()
{
List<TraceEventEntry> results = new();
await Context.Tracing.StartAsync(new()
{
Sources = true,
});

var page = await Context.NewPageAsync();
await page.GotoAsync(Server.Prefix + "/empty.html");
await page.SetContentAsync("<button>Click</button>");
await page.ClickAsync("\"Click\"");
await page.CloseAsync();

using var tmp = new TempDirectory();
var tracePath = Path.Combine(tmp.Path, "trace.zip");
await Context.Tracing.StopAsync(new() { Path = tracePath });

var (events, resources) = ParseTrace(tracePath);
var sourceNames = resources.Keys.Where(key => key.EndsWith(".txt")).ToArray();
Assert.AreEqual(sourceNames.Count(), 1);
var sourceTraceFileContent = resources[sourceNames[0]];
var currentFileContent = File.ReadAllText(new StackTrace(true).GetFrame(0).GetFileName());

Assert.AreEqual(sourceTraceFileContent, currentFileContent);
}

private static (IReadOnlyList<TraceEventEntry> Events, Dictionary<string, byte[]> Resources) ParseTrace(string path)
{
Dictionary<string, byte[]> resources = new();
var archive = ZipFile.OpenRead(path);
foreach (var events in new[] { archive.GetEntry("trace.trace"), archive.GetEntry("trace.network") })
foreach (var entry in archive.Entries)
{
var memoryStream = new MemoryStream();
entry.Open().CopyTo(memoryStream);
resources.Add(entry.Name, memoryStream.ToArray());
}
List<TraceEventEntry> events = new();
foreach (var fileName in new[] { "trace.trace", "trace.network" })
{
if (events != null)
foreach (var line in Encoding.UTF8.GetString(resources[fileName]).Split("\n"))
{
var reader = new StreamReader(events.Open());
while (true)
if (!string.IsNullOrEmpty(line))
{
var line = reader.ReadLine();
if (line == null) break;
results.Add(JsonSerializer.Deserialize<TraceEventEntry>(line,
new JsonSerializerOptions()
{
PropertyNameCaseInsensitive = true,
}));
events.Add(JsonSerializer.Deserialize<TraceEventEntry>(line,
new JsonSerializerOptions()
{
PropertyNameCaseInsensitive = true,
}));
}
}
}
return results;
return (events, resources);
}

private class TraceEventEntry
Expand Down
3 changes: 2 additions & 1 deletion src/Playwright/API/Generated/IFrame.cs
Original file line number Diff line number Diff line change
Expand Up @@ -717,7 +717,8 @@ public partial interface IFrame
/// A selector to use when resolving DOM element. See <a href="./selectors.md">working
/// with selectors</a> for more details.
/// </param>
ILocator Locator(string selector);
/// <param name="options">Call options</param>
ILocator Locator(string selector, FrameLocatorOptions? options = default);

/// <summary>
/// <para>Returns frame's name attribute as specified in the tag.</para>
Expand Down
3 changes: 2 additions & 1 deletion src/Playwright/API/Generated/IFrameLocator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,8 @@ public partial interface IFrameLocator
/// A selector to use when resolving DOM element. See <a href="./selectors.md">working
/// with selectors</a> for more details.
/// </param>
ILocator Locator(string selector);
/// <param name="options">Call options</param>
ILocator Locator(string selector, FrameLocatorLocatorOptions? options = default);

/// <summary><para>Returns locator to the n-th matching frame.</para></summary>
/// <param name="index">
Expand Down
21 changes: 2 additions & 19 deletions src/Playwright/API/Generated/ILocator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -454,7 +454,8 @@ public partial interface ILocator
/// A selector to use when resolving DOM element. See <a href="./selectors.md">working
/// with selectors</a> for more details.
/// </param>
ILocator Locator(string selector);
/// <param name="options">Call options</param>
ILocator Locator(string selector, LocatorLocatorOptions? options = default);

/// <summary><para>Returns locator to the n-th matching element.</para></summary>
/// <param name="index">
Expand Down Expand Up @@ -977,24 +978,6 @@ public partial interface ILocator
/// </summary>
/// <param name="options">Call options</param>
Task WaitForAsync(LocatorWaitForOptions? options = default);

/// <summary>
/// <para>
/// Matches elements containing specified text somewhere inside, possibly in a child
/// or a descendant element. For example, <c>"Playwright"</c> matches <c>&lt;article&gt;&lt;div&gt;Playwright&lt;/div&gt;&lt;/article&gt;</c>.
/// </para>
/// </summary>
/// <param name="text">Text to filter by as a string or as a regular expression.</param>
ILocator WithText(string text);

/// <summary>
/// <para>
/// Matches elements containing specified text somewhere inside, possibly in a child
/// or a descendant element. For example, <c>"Playwright"</c> matches <c>&lt;article&gt;&lt;div&gt;Playwright&lt;/div&gt;&lt;/article&gt;</c>.
/// </para>
/// </summary>
/// <param name="text">Text to filter by as a string or as a regular expression.</param>
ILocator WithText(Regex text);
}
}

Expand Down
3 changes: 2 additions & 1 deletion src/Playwright/API/Generated/IPage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1151,7 +1151,8 @@ public partial interface IPage
/// A selector to use when resolving DOM element. See <a href="./selectors.md">working
/// with selectors</a> for more details.
/// </param>
ILocator Locator(string selector);
/// <param name="options">Call options</param>
ILocator Locator(string selector, PageLocatorOptions? options = default);

/// <summary>
/// <para>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,10 @@ public BrowserNewContextOptions(BrowserNewContextOptions clone)
/// baseURL: <c>http://localhost:3000/foo/</c> and navigating to <c>./bar.html</c> results
/// in <c>http://localhost:3000/foo/bar.html</c>
/// </description></item>
/// <item><description>
/// baseURL: <c>http://localhost:3000/foo</c> (without trailing slash) and navigating
/// to <c>./bar.html</c> results in <c>http://localhost:3000/bar.html</c>
/// </description></item>
/// </list>
/// </summary>
[JsonPropertyName("baseURL")]
Expand Down
4 changes: 4 additions & 0 deletions src/Playwright/API/Generated/Options/BrowserNewPageOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,10 @@ public BrowserNewPageOptions(BrowserNewPageOptions clone)
/// baseURL: <c>http://localhost:3000/foo/</c> and navigating to <c>./bar.html</c> results
/// in <c>http://localhost:3000/foo/bar.html</c>
/// </description></item>
/// <item><description>
/// baseURL: <c>http://localhost:3000/foo</c> (without trailing slash) and navigating
/// to <c>./bar.html</c> results in <c>http://localhost:3000/bar.html</c>
/// </description></item>
/// </list>
/// </summary>
[JsonPropertyName("baseURL")]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,10 @@ public BrowserTypeLaunchPersistentContextOptions(BrowserTypeLaunchPersistentCont
/// baseURL: <c>http://localhost:3000/foo/</c> and navigating to <c>./bar.html</c> results
/// in <c>http://localhost:3000/foo/bar.html</c>
/// </description></item>
/// <item><description>
/// baseURL: <c>http://localhost:3000/foo</c> (without trailing slash) and navigating
/// to <c>./bar.html</c> results in <c>http://localhost:3000/bar.html</c>
/// </description></item>
/// </list>
/// </summary>
[JsonPropertyName("baseURL")]
Expand Down
Loading