Skip to content
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

add net8.0 target #3080

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
1 change: 1 addition & 0 deletions src/.editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ dotnet_diagnostic.CA1305.severity = error
dotnet_diagnostic.CA1307.severity = none
dotnet_diagnostic.CA1308.severity = none
dotnet_diagnostic.CA1508.severity = none
dotnet_diagnostic.CA1510.severity = none
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Disabled CA1510 because the throw helpers are not available on netstandard2.0 and #ifing this is not worth it.

dotnet_diagnostic.CA1725.severity = error
dotnet_diagnostic.CA1801.severity = suggestion
dotnet_diagnostic.CA1812.severity = none
Expand Down
4 changes: 0 additions & 4 deletions src/Common/Dependencies.props
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,6 @@
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="8.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is part of the SDK since .NET 5, so unnecessary.

see https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/overview?tabs=net-9

Starting in .NET 5, these analyzers are included with the .NET SDK and you don't need to install them separately.

<PackageReference Include="Microsoft.VisualStudio.Threading.Analyzers" Version="17.10.48">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
Expand Down
2 changes: 1 addition & 1 deletion src/Playwright.NUnit/Playwright.NUnit.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
and fixtures to enable using it within NUnit.
</Description>
<PackageIcon>icon.png</PackageIcon>
<TargetFrameworks>netcoreapp3.1;net462</TargetFrameworks>
<TargetFrameworks>net8.0;net462</TargetFrameworks>
<PublishRepositoryUrl>true</PublishRepositoryUrl>
<RunWithWarnings>true</RunWithWarnings>
<RootNamespace>Microsoft.Playwright.NUnit</RootNamespace>
Expand Down
2 changes: 1 addition & 1 deletion src/Playwright.NUnit/SkipAttribute.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ public void ApplyToTest(Test test)
{
if (_combinations.Any(combination =>
{
var requirements = (Enum.GetValues(typeof(Targets)) as Targets[]).Where(x => combination.HasFlag(x));
var requirements = ((Targets[])Enum.GetValues(typeof(Targets))).Where(x => combination.HasFlag(x));
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

to avoid null reference warning.

return requirements.All(flag =>
flag switch
{
Expand Down
2 changes: 1 addition & 1 deletion src/Playwright.Tests/PageEvaluateTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -549,7 +549,7 @@ public async Task ShouldNotLeakHandles()
[PlaywrightTest("page-evaluate.spec.ts", "should evaluate exception with a function on the stack")]
public async Task ShouldEvaluateExceptionWithAFunctionOnTheStack()
{
var exception = await Page.EvaluateAsync<Exception>(@"() => {
var exception = await Page.EvaluateAsync<PlaywrightException>(@"() => {
return (function functionOnStack() {
return new Error('error message');
})();
Expand Down
4 changes: 4 additions & 0 deletions src/Playwright/Core/APIRequest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,11 @@ async Task<IAPIRequestContext> IAPIRequest.NewContextAsync(APIRequestNewContextO
throw new PlaywrightException($"The specified storage state file does not exist: {options?.StorageStatePath}");
}

#if NET
storageState = await File.ReadAllTextAsync(options?.StorageStatePath).ConfigureAwait(false);
#else
storageState = File.ReadAllText(options?.StorageStatePath);
#endif
}
if (!string.IsNullOrEmpty(storageState))
{
Expand Down
4 changes: 4 additions & 0 deletions src/Playwright/Core/APIRequestContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,11 @@ await SendMessageToServerAsync<StorageState>("storageState").ConfigureAwait(fals

if (!string.IsNullOrEmpty(options?.Path))
{
#if NET
await File.WriteAllTextAsync(options?.Path, state).ConfigureAwait(false);
#else
File.WriteAllText(options?.Path, state);
#endif
}

return state;
Expand Down
4 changes: 4 additions & 0 deletions src/Playwright/Core/Browser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,11 @@ public async Task<IBrowserContext> NewContextAsync(BrowserNewContextOptions opti
throw new PlaywrightException($"The specified storage state file does not exist: {options.StorageStatePath}");
}

#if NET
storageState = await File.ReadAllTextAsync(options.StorageStatePath).ConfigureAwait(false);
#else
storageState = File.ReadAllText(options.StorageStatePath);
#endif
}

if (!string.IsNullOrEmpty(storageState))
Expand Down
4 changes: 4 additions & 0 deletions src/Playwright/Core/BrowserContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -544,7 +544,11 @@ await SendMessageToServerAsync<StorageState>("storageState").ConfigureAwait(fals

if (!string.IsNullOrEmpty(options?.Path))
{
#if NET
await File.WriteAllTextAsync(options?.Path, state).ConfigureAwait(false);
#else
File.WriteAllText(options?.Path, state);
#endif
}

return state;
Expand Down
2 changes: 2 additions & 0 deletions src/Playwright/Core/BrowserType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,9 @@ void ClosePipe()
{
pipe.CloseAsync().IgnoreException();
}
#pragma warning disable CA2000 // Dispose objects before losing scope
var connection = new Connection(_connection.LocalUtils);
#pragma warning restore CA2000 // Dispose objects before losing scope
connection.MarkAsRemote();
connection.Close += (_, _) => ClosePipe();

Expand Down
8 changes: 6 additions & 2 deletions src/Playwright/Core/ElementHandle.cs
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,11 @@ public async Task<byte[]> ScreenshotAsync(ElementHandleScreenshotOptions options
if (!string.IsNullOrEmpty(options.Path))
{
Directory.CreateDirectory(new FileInfo(options.Path).Directory.FullName);
#if NET
await File.WriteAllBytesAsync(options.Path, result).ConfigureAwait(false);
#else
File.WriteAllBytes(options.Path, result);
#endif
}

return result;
Expand Down Expand Up @@ -204,7 +208,7 @@ public async Task SetInputFilesAsync(IEnumerable<string> files, ElementHandleSet
{
throw new PlaywrightException("Cannot set input files to detached element.");
}
var converted = await SetInputFilesHelpers.ConvertInputFilesAsync(files, (BrowserContext)frame.Page.Context).ConfigureAwait(false);
var converted = await SetInputFilesHelpers.ConvertInputFilesAsync(files.ToList(), (BrowserContext)frame.Page.Context).ConfigureAwait(false);
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This API was changed to accept a List because of CA1851.

await SendMessageToServerAsync("setInputFiles", new Dictionary<string, object>
{
["payloads"] = converted.Payloads,
Expand All @@ -221,7 +225,7 @@ public Task SetInputFilesAsync(FilePayload files, ElementHandleSetInputFilesOpti

public async Task SetInputFilesAsync(IEnumerable<FilePayload> files, ElementHandleSetInputFilesOptions options = default)
{
var converted = SetInputFilesHelpers.ConvertInputFiles(files);
var converted = SetInputFilesHelpers.ConvertInputFiles(files.ToList());
await SendMessageToServerAsync("setInputFiles", new Dictionary<string, object>
{
["payloads"] = converted.Payloads,
Expand Down
15 changes: 12 additions & 3 deletions src/Playwright/Core/Frame.cs
Original file line number Diff line number Diff line change
Expand Up @@ -478,7 +478,12 @@ public async Task<IElementHandle> AddScriptTagAsync(FrameAddScriptTagOptions opt
var content = options?.Content;
if (!string.IsNullOrEmpty(options?.Path))
{
content = ScriptsHelper.AddSourceUrlToScript(File.ReadAllText(options.Path), options.Path);
#if NET
string source = await File.ReadAllTextAsync(options.Path).ConfigureAwait(false);
#else
string source = File.ReadAllText(options.Path);
#endif
content = ScriptsHelper.AddSourceUrlToScript(source, options.Path);
}

return await SendMessageToServerAsync<ElementHandle>("addScriptTag", new Dictionary<string, object>
Expand All @@ -496,7 +501,11 @@ public async Task<IElementHandle> AddStyleTagAsync(FrameAddStyleTagOptions optio
var content = options?.Content;
if (!string.IsNullOrEmpty(options?.Path))
{
#if NET
content = await File.ReadAllTextAsync(options.Path).ConfigureAwait(false);
#else
content = File.ReadAllText(options.Path);
#endif
content += "//# sourceURL=" + options.Path.Replace("\n", string.Empty);
}

Expand All @@ -515,7 +524,7 @@ public Task SetInputFilesAsync(string selector, string files, FrameSetInputFiles
[MethodImpl(MethodImplOptions.NoInlining)]
public async Task SetInputFilesAsync(string selector, IEnumerable<string> files, FrameSetInputFilesOptions options = default)
{
var converted = await SetInputFilesHelpers.ConvertInputFilesAsync(files, (BrowserContext)Page.Context).ConfigureAwait(false);
var converted = await SetInputFilesHelpers.ConvertInputFilesAsync(files.ToList(), (BrowserContext)Page.Context).ConfigureAwait(false);
#pragma warning disable CS0612 // Type or member is obsolete
await _setInputFilesAsync(selector, converted, options?.NoWaitAfter, options?.Timeout, options?.Strict).ConfigureAwait(false);
#pragma warning restore CS0612 // Type or member is obsolete
Expand All @@ -528,7 +537,7 @@ public Task SetInputFilesAsync(string selector, FilePayload files, FrameSetInput
[MethodImpl(MethodImplOptions.NoInlining)]
public async Task SetInputFilesAsync(string selector, IEnumerable<FilePayload> files, FrameSetInputFilesOptions options = default)
{
var converted = SetInputFilesHelpers.ConvertInputFiles(files);
var converted = SetInputFilesHelpers.ConvertInputFiles(files.ToList());
#pragma warning disable CS0612 // Type or member is obsolete
await _setInputFilesAsync(selector, converted, noWaitAfter: options?.NoWaitAfter, timeout: options?.Timeout, options?.Strict).ConfigureAwait(false);
#pragma warning restore CS0612 // Type or member is obsolete
Expand Down
8 changes: 8 additions & 0 deletions src/Playwright/Core/Page.cs
Original file line number Diff line number Diff line change
Expand Up @@ -711,7 +711,11 @@ public async Task<byte[]> ScreenshotAsync(PageScreenshotOptions options = defaul
if (!string.IsNullOrEmpty(options.Path))
{
Directory.CreateDirectory(new FileInfo(options.Path).Directory.FullName);
#if NET
await File.WriteAllBytesAsync(options.Path, result).ConfigureAwait(false);
#else
File.WriteAllBytes(options.Path, result);
#endif
}

return result;
Expand Down Expand Up @@ -916,7 +920,11 @@ public async Task<byte[]> PdfAsync(PagePdfOptions options = default)
if (!string.IsNullOrEmpty(options?.Path))
{
Directory.CreateDirectory(new FileInfo(options.Path).Directory.FullName);
#if NET
await File.WriteAllBytesAsync(options.Path, result).ConfigureAwait(false);
#else
File.WriteAllBytes(options.Path, result);
#endif
}

return result;
Expand Down
11 changes: 5 additions & 6 deletions src/Playwright/Core/Request.cs
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,11 @@ public IFrame Frame
var frame = _initializer.Frame;
if (frame.Page == null)
{
throw new PlaywrightException(string.Join("\n", new string[]
{
"Frame for this navigation request is not available, because the request",
"was issued before the frame is created. You can check whether the request",
"is a navigation request by calling isNavigationRequest() method.",
}));
throw new PlaywrightException("""
Frame for this navigation request is not available, because the request
was issued before the frame is created. You can check whether the request
is a navigation request by calling isNavigationRequest() method.
""");
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To fix CA1861.

}
return frame;
}
Expand Down
4 changes: 4 additions & 0 deletions src/Playwright/Core/Route.cs
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,11 @@ private async Task<Dictionary<string, object>> NormalizeFulfillParametersAsync(

if (!string.IsNullOrEmpty(path))
{
#if NET
byte[] content = await File.ReadAllBytesAsync(path).ConfigureAwait(false);
#else
byte[] content = File.ReadAllBytes(path);
#endif
resultBody = Convert.ToBase64String(content);
isBase64 = true;
length = resultBody.Length;
Expand Down
12 changes: 11 additions & 1 deletion src/Playwright/Core/Waiter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -150,10 +150,16 @@ internal void RejectOnTimeout(int? timeout, string message)
return;
}

#pragma warning disable CA2000 // Dispose objects before losing scope
var cts = new CancellationTokenSource();
#pragma warning restore CA2000 // Dispose objects before losing scope
RejectOn(
new TaskCompletionSource<bool>().Task.WithTimeout(timeout.Value, _ => new TimeoutException(message), cts.Token),
() => cts.Cancel());
() =>
{
cts.Cancel();
cts.Dispose();
});
}

internal Task<T> WaitForEventAsync<T>(object eventSource, string e, Func<T, bool> predicate)
Expand Down Expand Up @@ -250,7 +256,11 @@ private static async Task WrapActionAsync(Func<Task> action, CancellationTokenSo
}
catch
{
#if NET
await cts.CancelAsync().ConfigureAwait(false);
#else
cts.Cancel();
#endif
throw;
}
}
Expand Down
9 changes: 7 additions & 2 deletions src/Playwright/Helpers/Driver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -100,9 +100,14 @@ private static bool TryGetCodeBase(Assembly assembly, out Uri codeBase)
{
try
{
// assembly.CodeBase might throw with:
// System.NotSupportedException: CodeBase is not supported on assemblies loaded from a single-file bundle.
// assembly.Location/CodeBase might throw with:
// System.NotSupportedException: Location/CodeBase is not supported on assemblies loaded from a single-file bundle.
// Still using CodeBase for legacy .NET because of behaviour difference with shadow-copy (see https://learn.microsoft.com/en-us/dotnet/api/system.reflection.assembly.location?view=net-8.0#remarks)
#if NET
Uri.TryCreate(assembly.Location, UriKind.Absolute, out codeBase);
#else
Uri.TryCreate(assembly.CodeBase, UriKind.Absolute, out codeBase);
#endif
return true;
}
catch (NotSupportedException)
Expand Down
18 changes: 9 additions & 9 deletions src/Playwright/Helpers/SetInputFilesHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ private static (string[] LocalPaths, string LocalDirectory) ResolvePathsAndDirec
return (localPaths?.ToArray(), localDirectory);
}

private static IEnumerable<string> GetFilesRecursive(string directory)
private static List<string> GetFilesRecursive(string directory)
{
var files = new List<string>();
files.AddRange(Directory.GetFiles(directory));
Expand All @@ -76,16 +76,16 @@ private static IEnumerable<string> GetFilesRecursive(string directory)
return files;
}

public static async Task<SetInputFilesFiles> ConvertInputFilesAsync(IEnumerable<string> files, BrowserContext context)
public static async Task<SetInputFilesFiles> ConvertInputFilesAsync(List<string> files, BrowserContext context)
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as mentioned above: This API was changed to accept a List because of CA1851.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If they were to accept a breaking change then IReadOnlyCollection would allow you to pass in both and array and a list interchangeably whilst keeping the compiler happy.

{
if (!files.Any())
if (files.Count == 0)
{
return new() { Payloads = [] };
}
var (localPaths, localDirectory) = ResolvePathsAndDirectoryForInputFiles(files.ToList());
var (localPaths, localDirectory) = ResolvePathsAndDirectoryForInputFiles(files);
if (context._connection.IsRemote)
{
files = localDirectory != null ? GetFilesRecursive(localDirectory) : localPaths;
files = localDirectory != null ? GetFilesRecursive(localDirectory) : localPaths.ToList();
var result = await context.SendMessageToServerAsync("createTempFiles", new Dictionary<string, object>
{
["rootDirName"] = localDirectory != null ? new DirectoryInfo(localDirectory).Name : null,
Expand All @@ -97,12 +97,12 @@ public static async Task<SetInputFilesFiles> ConvertInputFilesAsync(IEnumerable<
}).ToArray(),
}).ConfigureAwait(false);
var writableStreams = result.Value.GetProperty("writableStreams").EnumerateArray();
if (writableStreams.Count() != files.Count())
if (writableStreams.Count() != files.Count)
{
throw new Exception("Mismatch between the number of files and the number of writeable streams");
throw new PlaywrightException("Mismatch between the number of files and the number of writeable streams");
}
var streams = new List<WritableStream>();
for (var i = 0; i < files.Count(); i++)
for (var i = 0; i < files.Count; i++)
{
#pragma warning disable CA2007 // Consider calling ConfigureAwait on the awaited task
await using (var writeableStream = context._connection.GetObject(writableStreams.ElementAt(i).GetProperty("guid").ToString()) as WritableStream)
Expand All @@ -122,7 +122,7 @@ public static async Task<SetInputFilesFiles> ConvertInputFilesAsync(IEnumerable<
return new() { LocalPaths = localPaths, LocalDirectory = localDirectory };
}

public static SetInputFilesFiles ConvertInputFiles(IEnumerable<FilePayload> files)
public static SetInputFilesFiles ConvertInputFiles(List<FilePayload> files)
{
var filePayloadExceedsSizeLimit = files.Sum(f => f.Buffer.Length) > SizeLimitInBytes;
if (filePayloadExceedsSizeLimit)
Expand Down
4 changes: 4 additions & 0 deletions src/Playwright/Helpers/StringExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -615,7 +615,11 @@ public static Dictionary<string, string> ParseQueryString(this string query)

var result = new Dictionary<string, string>();

#if NET
if (query.StartsWith('?'))
#else
if (query.StartsWith("?", StringComparison.InvariantCultureIgnoreCase))
#endif
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To fix CA1867.

{
query = query.Substring(1, query.Length - 1);
}
Expand Down
4 changes: 4 additions & 0 deletions src/Playwright/Helpers/URLMatch.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,11 @@ public bool Match(string url)
internal static string JoinWithBaseURL(string baseUrl, string url)
{
if (string.IsNullOrEmpty(baseUrl)
#if NET
|| (url?.StartsWith('*') ?? false)
#else
|| (url?.StartsWith("*", StringComparison.InvariantCultureIgnoreCase) ?? false)
#endif
|| !Uri.IsWellFormedUriString(url, UriKind.RelativeOrAbsolute))
{
return url;
Expand Down
2 changes: 2 additions & 0 deletions src/Playwright/Playwright.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,10 @@ public static class Playwright
/// <returns>A <see cref="Task"/> that completes when the playwright driver is ready to be used.</returns>
public static async Task<IPlaywright> CreateAsync()
{
#pragma warning disable CA2000 // Dispose objects before losing scope
var transport = new StdIOTransport();
var connection = new Connection();
#pragma warning restore CA2000 // Dispose objects before losing scope
transport.MessageReceived += (_, message) =>
{
Connection.TraceMessage("pw:channel:recv", message);
Expand Down
10 changes: 6 additions & 4 deletions src/Playwright/Playwright.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<Summary>The .NET port of Playwright, used to automate Chromium, Firefox and WebKit with a single API.</Summary>
<Description>Playwright enables reliable end-to-end testing for modern web apps. It is built to enable cross-browser web automation that is ever-green, capable, reliable and fast. Learn more at https://playwright.dev/dotnet/.</Description>
<PackageIcon>icon.png</PackageIcon>
<TargetFramework>netstandard2.0</TargetFramework>
<TargetFrameworks>netstandard2.0;net8.0</TargetFrameworks>
<PublishRepositoryUrl>true</PublishRepositoryUrl>
<DocumentationFile>Microsoft.Playwright.xml</DocumentationFile>
<RunWithWarnings>true</RunWithWarnings>
Expand All @@ -25,15 +25,17 @@
<Import Project="../Common/Dependencies.props" />
<Import Project="../Common/SignAssembly.props" />
<Import Project="../Common/SignFiles.props" />
<ItemGroup Condition="'$(TargetFramework)'== 'netstandard2.0'">
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
<PackageReference Include="System.Text.Json" Version="6.0.10" />
<PackageReference Include="Microsoft.Bcl.AsyncInterfaces" Version="6.0.0" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.VisualStudioEng.MicroBuild.Core" Version="1.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
<PackageReference Include="System.Text.Json" Version="6.0.10" />
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="8.0.0" PrivateAssets="All" />
<PackageReference Include="Microsoft.Bcl.AsyncInterfaces" Version="6.0.0" />
</ItemGroup>
<ItemGroup>
<InternalsVisibleTo Include="Microsoft.Playwright.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100059a04ca5ca77c9b4eb2addd1afe3f8464b20ee6aefe73b8c23c0e6ca278d1a378b33382e7e18d4aa8300dd22d81f146e528d88368f73a288e5b8157da9710fe6f9fa9911fb786193f983408c5ebae0b1ba5d1d00111af2816f5db55871db03d7536f4a7a6c5152d630c1e1886b1a0fb68ba5e7f64a7f24ac372090889be2ffb" />
Expand Down
Loading
Loading