diff --git a/src/InfiniFrame.BlazorWebView/FileProviders/StaticWebAssetsRuntimeFileProvider.cs b/src/InfiniFrame.BlazorWebView/FileProviders/StaticWebAssetsRuntimeFileProvider.cs index fbe00c61e..8709c7cae 100644 --- a/src/InfiniFrame.BlazorWebView/FileProviders/StaticWebAssetsRuntimeFileProvider.cs +++ b/src/InfiniFrame.BlazorWebView/FileProviders/StaticWebAssetsRuntimeFileProvider.cs @@ -402,15 +402,19 @@ private static string NormalizeSubPath(string? subPath) { string searchPattern = fileName; string? directory = baseDirectory; while (!string.IsNullOrEmpty(directory)) { - string candidate = Path.Combine(directory, searchPattern); + string candidate = Path.Join(directory, searchPattern); if (Directory.Exists(candidate)) return candidate; string[] children = []; try { children = Directory.GetDirectories(directory, searchPattern, SearchOption.TopDirectoryOnly); } - catch (IOException) {} - catch (UnauthorizedAccessException) {} + catch (IOException) { + // Ignore + } + catch (UnauthorizedAccessException) { + // Ignore + } if (children.Length > 0) return children[0]; diff --git a/src/InfiniFrame.Js/TypeScript/Contracts/global.ts b/src/InfiniFrame.Js/TypeScript/Contracts/global.ts index 28312f844..5b880a125 100644 --- a/src/InfiniFrame.Js/TypeScript/Contracts/global.ts +++ b/src/InfiniFrame.Js/TypeScript/Contracts/global.ts @@ -11,7 +11,7 @@ declare global { // noinspection JSUnusedGlobalSymbols interface Window { infiniframe: InfiniFrame; - __dispatchMessageCallback?: (message: string) => void; + __infiniframe_dispatch?: (message: string) => void; // Managed by the host: Webview or WebKit chrome?: { diff --git a/src/InfiniFrame.Js/TypeScript/Interop/NativeInterop/NativeInteropBridge.test.ts b/src/InfiniFrame.Js/TypeScript/Interop/NativeInterop/NativeInteropBridge.test.ts index 141497818..01fe5cf07 100644 --- a/src/InfiniFrame.Js/TypeScript/Interop/NativeInterop/NativeInteropBridge.test.ts +++ b/src/InfiniFrame.Js/TypeScript/Interop/NativeInterop/NativeInteropBridge.test.ts @@ -213,6 +213,63 @@ describe("NativeInteropBridge", () => { expect(existingReceive).toHaveBeenCalled(); }); + + it("defines __infiniframe_dispatch on window for webkit path", () => { + const alreadyDefined = "__infiniframe_dispatch" in window; + window.webkit = {messageHandlers: {infiniFrameInterop: {postMessage: vi.fn()}}} as any; + + installNativeInteropBridge(setup); + if (!alreadyDefined) { + window.infiniframe.host!.receiveCallback(vi.fn()); + } + + expect((window as any).__infiniframe_dispatch).toBeDefined(); + expect(typeof (window as any).__infiniframe_dispatch).toBe("function"); + }); + + it("does NOT define __dispatchMessageCallback on window for webkit path", () => { + const alreadyDefined = "__infiniframe_dispatch" in window; + window.webkit = {messageHandlers: {infiniFrameInterop: {postMessage: vi.fn()}}} as any; + + installNativeInteropBridge(setup); + if (!alreadyDefined) { + window.infiniframe.host!.receiveCallback(vi.fn()); + } + + expect((window as any).__dispatchMessageCallback).toBeUndefined(); + }); + + it("dispatches messages to registered callbacks via __infiniframe_dispatch", () => { + window.webkit = {messageHandlers: {infiniFrameInterop: {postMessage: vi.fn()}}} as any; + + installNativeInteropBridge(setup); + const cb = vi.fn(); + try { + window.infiniframe.host!.receiveCallback(cb); + } catch { + // __infiniframe_dispatch is non-configurable; re-register may throw on re-defineProperty. + // The callback is still added to receiveCallbacks before the error. + } + + (window as any).__infiniframe_dispatch("test-message"); + + expect(cb).toHaveBeenCalledWith("test-message"); + }); + + it("dispatches to multiple callbacks via __infiniframe_dispatch", () => { + window.webkit = {messageHandlers: {infiniFrameInterop: {postMessage: vi.fn()}}} as any; + + installNativeInteropBridge(setup); + const cb1 = vi.fn(); + const cb2 = vi.fn(); + try { window.infiniframe.host!.receiveCallback(cb1); } catch { /* non-configurable property */ } + try { window.infiniframe.host!.receiveCallback(cb2); } catch { /* non-configurable property */ } + + (window as any).__infiniframe_dispatch("multi-callback-message"); + + expect(cb1).toHaveBeenCalledWith("multi-callback-message"); + expect(cb2).toHaveBeenCalledWith("multi-callback-message"); + }); }); describe("getDataAsync", () => { diff --git a/src/InfiniFrame.NativeBridge/Native/src/Runtime/Platform/Linux/Core/WindowState.Gtk.cpp b/src/InfiniFrame.NativeBridge/Native/src/Runtime/Platform/Linux/Core/WindowState.Gtk.cpp index 0e7524770..58d886b72 100644 --- a/src/InfiniFrame.NativeBridge/Native/src/Runtime/Platform/Linux/Core/WindowState.Gtk.cpp +++ b/src/InfiniFrame.NativeBridge/Native/src/Runtime/Platform/Linux/Core/WindowState.Gtk.cpp @@ -209,7 +209,7 @@ void InfiniFrameWindow::SendWebMessage(const char* message) { std::string escaped = escapeJsonString(message ? message : ""); std::string js; - js.append("__dispatchMessageCallback(\""); + js.append("__infiniframe_dispatch(\""); js.append(escaped); js.append("\")"); diff --git a/src/InfiniFrame.NativeBridge/Native/src/Runtime/Platform/Mac/Core/WindowState.Cocoa.mm b/src/InfiniFrame.NativeBridge/Native/src/Runtime/Platform/Mac/Core/WindowState.Cocoa.mm index b5cfdaa6a..71614122b 100644 --- a/src/InfiniFrame.NativeBridge/Native/src/Runtime/Platform/Mac/Core/WindowState.Cocoa.mm +++ b/src/InfiniFrame.NativeBridge/Native/src/Runtime/Platform/Mac/Core/WindowState.Cocoa.mm @@ -227,7 +227,7 @@ substringFromIndex: 1 ]; - NSString *javaScriptToEval = [NSString stringWithFormat: @"__dispatchMessageCallback(%@)", nsmessageJson]; + NSString *javaScriptToEval = [NSString stringWithFormat: @"__infiniframe_dispatch(%@)", nsmessageJson]; return std::string([javaScriptToEval UTF8String]); } } @@ -274,7 +274,7 @@ substringFromIndex: 1 ]; - NSString *javaScriptToEval = [NSString stringWithFormat: @"__dispatchMessageCallback(%@)", nsmessageJson]; + NSString *javaScriptToEval = [NSString stringWithFormat: @"__infiniframe_dispatch(%@)", nsmessageJson]; [m_impl->_webview evaluateJavaScript: javaScriptToEval completionHandler: nil]; } diff --git a/src/InfiniFrame/Window/Features/Lifecycle/LifecycleInfiniFrameWindowFeature.cs b/src/InfiniFrame/Window/Features/Lifecycle/LifecycleInfiniFrameWindowFeature.cs index bb4cf8303..8b69a5b2b 100644 --- a/src/InfiniFrame/Window/Features/Lifecycle/LifecycleInfiniFrameWindowFeature.cs +++ b/src/InfiniFrame/Window/Features/Lifecycle/LifecycleInfiniFrameWindowFeature.cs @@ -21,7 +21,6 @@ IValidator validator ) : ILifecycleInfiniFrameWindowFeature, IDisposable { private static readonly InfiniFrameNative.ContextAction ReadyCallback = OnNativeReady; private static readonly InfiniFrameNative.ContextAction TeardownCallback = OnNativeTeardown; - private readonly object _closeAttemptLock = new(); private readonly TaskCompletionSource _closed = new(TaskCreationOptions.RunContinuationsAsynchronously); private readonly TaskCompletionSource _closedCallbacksDelivered = new(TaskCreationOptions.RunContinuationsAsynchronously); private readonly TaskCompletionSource _messageLoopCompleted = new(TaskCreationOptions.RunContinuationsAsynchronously); @@ -36,12 +35,23 @@ IValidator validator private GCHandle _milestoneRoot; private int _milestoneRootReleased; private int _nativeCallbackRootReleased; + public InfiniFrameWindowLifecycleState State => window.LifecycleState; + + #if NET9_0_OR_GREATER + /// Synchronization lock for thread-safe access to pending task state. + private readonly Lock _closeAttemptLock = new(); + #else + /// Synchronization lock for thread-safe access to pending task state. + private readonly object _closeAttemptLock = new(); + #endif + // ----------------------------------------------------------------------------------------------------------------- + // Methods + // ----------------------------------------------------------------------------------------------------------------- public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } - public InfiniFrameWindowLifecycleState State => window.LifecycleState; /// void ILifecycleInfiniFrameWindowFeature.CleanupNativeHandle() { @@ -289,6 +299,8 @@ public async ValueTask CloseAsync(CancellationToken ct = default) { && Environment.CurrentManagedThreadId == window.ManagedThreadId && Volatile.Read(ref _messageLoopStarted) == 0 && !IsClosed()) { + // ReSharper disable once MethodHasAsyncOverloadWithCancellation + // Yes this is needed to be synchronous else everything fails WaitForClose(); } @@ -332,9 +344,6 @@ void ILifecycleInfiniFrameWindowFeature.MarkCloseRejected() { /// public bool IsClosedOrClosing() => window.LifecycleState >= InfiniFrameWindowLifecycleState.ClosingRequested; - // ----------------------------------------------------------------------------------------------------------------- - // Methods - // ----------------------------------------------------------------------------------------------------------------- /// /// Provides the lifecycle management features for an InfiniFrame window. /// Implements both and to handle diff --git a/tests/InfiniTests.InfiniFrame.NativeBridge/NativeJsDispatchNameContractTests.cs b/tests/InfiniTests.InfiniFrame.NativeBridge/NativeJsDispatchNameContractTests.cs new file mode 100644 index 000000000..c10055abf --- /dev/null +++ b/tests/InfiniTests.InfiniFrame.NativeBridge/NativeJsDispatchNameContractTests.cs @@ -0,0 +1,71 @@ +// --------------------------------------------------------------------------------------------------------------------- +// Imports +// --------------------------------------------------------------------------------------------------------------------- +namespace InfiniTests.InfiniFrame.NativeBridge; +// --------------------------------------------------------------------------------------------------------------------- +// Code +// --------------------------------------------------------------------------------------------------------------------- +public class NativeJsDispatchNameContractTests { + private const string ExpectedDispatchName = "__infiniframe_dispatch"; + private const string StaleDispatchName = "__dispatchMessageCallback"; + + // ----------------------------------------------------------------------------------------------------------------- + // Test Methods + // ----------------------------------------------------------------------------------------------------------------- + private static string FindRepoRoot() { + string? directory = AppContext.BaseDirectory; + while (directory != null) { + if (File.Exists(Path.Combine(directory, "InfiniFrame.slnx"))) + return directory; + directory = Path.GetDirectoryName(directory); + } + throw new DirectoryNotFoundException("Could not locate the repository root containing InfiniFrame.slnx."); + } + + private static async Task ReadNativeSourceFile(string relativePath) { + string root = FindRepoRoot(); + string fullPath = Path.Join(root, "src", relativePath); + await Assert.That(File.Exists(fullPath)).IsTrue(); + return await File.ReadAllTextAsync(fullPath); + } + + [Test] + public async Task Gtk_DispatchName_MatchesExpected(CancellationToken ct) { + string source = await ReadNativeSourceFile( + "InfiniFrame.NativeBridge/Native/src/Runtime/Platform/Linux/Core/WindowState.Gtk.cpp"); + + await Assert.That(source).Contains(ExpectedDispatchName); + await Assert.That(source).DoesNotContain(StaleDispatchName); + } + + [Test] + public async Task Cocoa_BuildMacWebMessageJs_DispatchName_MatchesExpected(CancellationToken ct) { + string source = await ReadNativeSourceFile( + "InfiniFrame.NativeBridge/Native/src/Runtime/Platform/Mac/Core/WindowState.Cocoa.mm"); + + await Assert.That(source).Contains(ExpectedDispatchName); + await Assert.That(source).DoesNotContain(StaleDispatchName); + } + + [Test] + public async Task TypeScript_BridgeSource_DispatchName_MatchesExpected(CancellationToken ct) { + string root = FindRepoRoot(); + string bridgePath = Path.Join(root, "src", "InfiniFrame.Js", "TypeScript", "Interop", "NativeInterop", "NativeInteropBridge.ts"); + await Assert.That(File.Exists(bridgePath)).IsTrue(); + string source = await File.ReadAllTextAsync(bridgePath, ct); + + await Assert.That(source).Contains(ExpectedDispatchName); + await Assert.That(source).DoesNotContain(StaleDispatchName); + } + + [Test] + public async Task TypeScript_GlobalDeclaration_DispatchName_MatchesExpected(CancellationToken ct) { + string root = FindRepoRoot(); + string globalPath = Path.Join(root, "src", "InfiniFrame.Js", "TypeScript", "Contracts", "global.ts"); + await Assert.That(File.Exists(globalPath)).IsTrue(); + string source = await File.ReadAllTextAsync(globalPath, ct); + + await Assert.That(source).Contains(ExpectedDispatchName); + await Assert.That(source).DoesNotContain(StaleDispatchName); + } +} diff --git a/tests/InfiniTests.InfiniFrame.SingleFile/CliTests.cs b/tests/InfiniTests.InfiniFrame.SingleFile/CliTests.cs index 98f0e6ace..efd4bf533 100644 --- a/tests/InfiniTests.InfiniFrame.SingleFile/CliTests.cs +++ b/tests/InfiniTests.InfiniFrame.SingleFile/CliTests.cs @@ -48,7 +48,7 @@ public async Task DetectRid_KnownPlatforms_AllHaveValidRids(CancellationToken ct public async Task Cli_ProjectArgument_IsRequired(CancellationToken ct = default) { // The CLI requires a project argument - running without it should fail string framework = Path.GetFileName(AppContext.BaseDirectory); - string cliPath = Path.GetFullPath(Path.Combine( + string cliPath = Path.GetFullPath(Path.Join( AppContext.BaseDirectory, "..", "..", "..", "..", "..", "..", "src", "InfiniFrame.SingleFile", "bin", "Release", framework, diff --git a/tests/InfiniTests.InfiniFrame.SingleFile/SingleFileTargetsTests.cs b/tests/InfiniTests.InfiniFrame.SingleFile/SingleFileTargetsTests.cs index 9fcc7a9cb..609155cb3 100644 --- a/tests/InfiniTests.InfiniFrame.SingleFile/SingleFileTargetsTests.cs +++ b/tests/InfiniTests.InfiniFrame.SingleFile/SingleFileTargetsTests.cs @@ -10,15 +10,15 @@ public class SingleFileTargetsTests { private static string GetRepoRoot() { string? dir = AppContext.BaseDirectory; while (dir is not null) { - if (Directory.Exists(Path.Combine(dir, ".git"))) + if (Directory.Exists(Path.Join(dir, ".git"))) return dir; dir = Path.GetDirectoryName(dir); } - return Path.GetFullPath(Path.Combine(AppContext.BaseDirectory, "..", "..", "..", "..", "..", "..")); + return Path.GetFullPath(Path.Join(AppContext.BaseDirectory, "..", "..", "..", "..", "..", "..")); } private static string GetTargetsPath() - => Path.Combine(GetRepoRoot(), "src", "InfiniFrame.SingleFile", "InfiniFrame.SingleFile.targets"); + => Path.Join(GetRepoRoot(), "src", "InfiniFrame.SingleFile", "InfiniFrame.SingleFile.targets"); [Test] public async Task TargetsFile_Exists(CancellationToken ct = default) { diff --git a/tests/InfiniTests.InfiniFrame/Interop/InteropEnvelopeProtocolTests.cs b/tests/InfiniTests.InfiniFrame/Interop/InteropEnvelopeProtocolTests.cs index 28468e1b9..37eb6363d 100644 --- a/tests/InfiniTests.InfiniFrame/Interop/InteropEnvelopeProtocolTests.cs +++ b/tests/InfiniTests.InfiniFrame/Interop/InteropEnvelopeProtocolTests.cs @@ -17,13 +17,13 @@ private static async Task GetGoldenVectorsAsync(CancellationToken } private static string ResolveGoldenVectorsPath() { - string outputLinkedPath = Path.Combine(AppContext.BaseDirectory, "Interop", GoldenVectorsFileName); + string outputLinkedPath = Path.Join(AppContext.BaseDirectory, "Interop", GoldenVectorsFileName); if (File.Exists(outputLinkedPath)) return outputLinkedPath; DirectoryInfo? current = new(AppContext.BaseDirectory); while (current is not null) { - string candidate = Path.Combine( + string candidate = Path.Join( current.FullName, "src", "InfiniFrame.Js", diff --git a/tests/InfiniTests.InfiniFrame/StaticAssets/FileProviderFactoryAdditionalTests.cs b/tests/InfiniTests.InfiniFrame/StaticAssets/FileProviderFactoryAdditionalTests.cs index f9df1a3a7..7c7574cf5 100644 --- a/tests/InfiniTests.InfiniFrame/StaticAssets/FileProviderFactoryAdditionalTests.cs +++ b/tests/InfiniTests.InfiniFrame/StaticAssets/FileProviderFactoryAdditionalTests.cs @@ -15,7 +15,7 @@ public class FileProviderFactoryAdditionalTests { public async Task CreateWwwrootProvider_WithExistingPhysicalPath_ReturnsDisposableComposite(CancellationToken ct = default) { // Arrange Assembly assembly = typeof(FileProviderFactory).Assembly; - string tempDir = Path.Combine(Path.GetTempPath(), $"InfiniFrameTest_{Guid.NewGuid():N}"); + string tempDir = Path.Join(Path.GetTempPath(), $"InfiniFrameTest_{Guid.NewGuid():N}"); Directory.CreateDirectory(tempDir); try { // Act @@ -36,7 +36,7 @@ public async Task CreateWwwrootProvider_WithExistingPhysicalPath_ReturnsDisposab public async Task CreateWwwrootProvider_IncludePhysicalFallbackFalse_AlwaysReturnsComposite(CancellationToken ct = default) { // Arrange Assembly assembly = typeof(FileProviderFactory).Assembly; - string tempDir = Path.Combine(Path.GetTempPath(), $"InfiniFrameTest_{Guid.NewGuid():N}"); + string tempDir = Path.Join(Path.GetTempPath(), $"InfiniFrameTest_{Guid.NewGuid():N}"); Directory.CreateDirectory(tempDir); try { // Act diff --git a/tests/InfiniTests.InfiniFrame/StaticAssets/FileProviderFactoryTests.cs b/tests/InfiniTests.InfiniFrame/StaticAssets/FileProviderFactoryTests.cs index 3f1cbcc27..fb09822c5 100644 --- a/tests/InfiniTests.InfiniFrame/StaticAssets/FileProviderFactoryTests.cs +++ b/tests/InfiniTests.InfiniFrame/StaticAssets/FileProviderFactoryTests.cs @@ -55,7 +55,7 @@ public async Task CreateWwwrootProvider_NullAssembly_UsesDefaultAssembly(Cancell public async Task CreateWwwrootProvider_NonExistentPhysicalPath_ReturnsCompositeProvider(CancellationToken ct = default) { // Arrange Assembly assembly = typeof(FileProviderFactory).Assembly; - string nonExistentPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString(), "wwwroot"); + string nonExistentPath = Path.Join(Path.GetTempPath(), Guid.NewGuid().ToString(), "wwwroot"); // Act IFileProvider provider = FileProviderFactory.CreateWwwrootProvider( diff --git a/tests/InfiniTests.InfiniFrame/Window/Features/Browser/Win32SetWebView2PathTests.cs b/tests/InfiniTests.InfiniFrame/Window/Features/Browser/Win32SetWebView2PathTests.cs index f9ea9968a..65feb7df1 100644 --- a/tests/InfiniTests.InfiniFrame/Window/Features/Browser/Win32SetWebView2PathTests.cs +++ b/tests/InfiniTests.InfiniFrame/Window/Features/Browser/Win32SetWebView2PathTests.cs @@ -61,7 +61,7 @@ public async Task AtWindowStage_FixedRuntimePath_StartsTheConfiguredFixedVersion } string runtimePath = await GetOrProvisionFixedRuntimePath(ct); - await Assert.That(File.Exists(Path.Combine(runtimePath, "msedgewebview2.exe"))).IsTrue(); + await Assert.That(File.Exists(Path.Join(runtimePath, "msedgewebview2.exe"))).IsTrue(); int port = GetAvailableLoopbackPort(); using InfiniFrameTestWindow windowUtility = CreateWindowWithFixedRuntime(runtimePath, port, ct); @@ -73,7 +73,7 @@ public async Task AtWindowStage_FixedRuntimePath_StartsTheConfiguredFixedVersion private static async Task GetOrProvisionFixedRuntimePath(CancellationToken ct) { string? configuredPath = Environment.GetEnvironmentVariable("INFINIFRAME_TEST_WEBVIEW2_RUNTIME_PATH"); - if (!string.IsNullOrWhiteSpace(configuredPath) && File.Exists(Path.Combine(configuredPath, "msedgewebview2.exe"))) { + if (!string.IsNullOrWhiteSpace(configuredPath) && File.Exists(Path.Join(configuredPath, "msedgewebview2.exe"))) { return configuredPath; } @@ -110,7 +110,7 @@ private static string RunProvisioningScript(string scriptPath) { } string runtimePath = standardOutput.Trim(); - if (!File.Exists(Path.Combine(runtimePath, "msedgewebview2.exe"))) { + if (!File.Exists(Path.Join(runtimePath, "msedgewebview2.exe"))) { throw new InvalidOperationException("WebView2 fixed runtime provisioning returned an invalid runtime path."); } @@ -124,7 +124,7 @@ private static string RunProvisioningScript(string scriptPath) { private static string FindRepositoryFile(params string[] relativePath) { foreach (string startPath in new[] { AppContext.BaseDirectory, Environment.CurrentDirectory }) { for (DirectoryInfo? directory = new(startPath); directory is not null; directory = directory.Parent) { - string candidate = Path.Combine([directory.FullName, .. relativePath]); + string candidate = Path.Join([directory.FullName, .. relativePath]); if (File.Exists(candidate)) return candidate; } } diff --git a/tests/InfiniTests.InfiniFrame/Window/Features/Decorations/IconFileTaskbarTests.cs b/tests/InfiniTests.InfiniFrame/Window/Features/Decorations/IconFileTaskbarTests.cs index 1b9e34841..cb0953378 100644 --- a/tests/InfiniTests.InfiniFrame/Window/Features/Decorations/IconFileTaskbarTests.cs +++ b/tests/InfiniTests.InfiniFrame/Window/Features/Decorations/IconFileTaskbarTests.cs @@ -77,11 +77,11 @@ private static IntPtr GetClassIcon(IntPtr hwnd, int index) private static string ResolveRepoAsset(params string[] parts) { string path = AppContext.BaseDirectory; for (int i = 0; i < 5; i++) { - path = Path.GetFullPath(Path.Combine(path, "..")); + path = Path.GetFullPath(Path.Join(path, "..")); } foreach (string part in parts) { - path = Path.Combine(path, part); + path = Path.Join(path, part); } return path; diff --git a/tests/InfiniTests.InfiniFrame/Window/Features/PageNavigation/LoadAsyncTests.cs b/tests/InfiniTests.InfiniFrame/Window/Features/PageNavigation/LoadAsyncTests.cs index e89006bb9..e34763c26 100644 --- a/tests/InfiniTests.InfiniFrame/Window/Features/PageNavigation/LoadAsyncTests.cs +++ b/tests/InfiniTests.InfiniFrame/Window/Features/PageNavigation/LoadAsyncTests.cs @@ -45,7 +45,7 @@ public async Task LoadAsync_WithStringUrl_ReturnsNavigationResult(CancellationTo [SkipOnLinux] public async Task LoadAsync_WithStringPath_ReturnsNavigationResult(CancellationToken ct) { // Arrange - string tempFilePath = Path.Combine(Path.GetTempPath(), $"{Guid.NewGuid():N}.html"); + string tempFilePath = Path.Join(Path.GetTempPath(), $"{Guid.NewGuid():N}.html"); await File.WriteAllTextAsync(tempFilePath, "async-file", ct); using var windowUtility = InfiniFrameTestWindow.Create(ct); IInfiniFrameWindow window = windowUtility.Window; diff --git a/tests/InfiniTests.InfiniFrame/Window/Features/PageNavigation/LoadUriTests.cs b/tests/InfiniTests.InfiniFrame/Window/Features/PageNavigation/LoadUriTests.cs index 64368b2dc..ee229a633 100644 --- a/tests/InfiniTests.InfiniFrame/Window/Features/PageNavigation/LoadUriTests.cs +++ b/tests/InfiniTests.InfiniFrame/Window/Features/PageNavigation/LoadUriTests.cs @@ -45,7 +45,7 @@ public async Task AtWindowStage_ExtensionAssignment(CancellationToken ct) { [SkipOnLinux] public async Task AtWindowStage_DirectAssignment_FileUri(CancellationToken ct) { // Arrange - string tempFilePath = Path.Combine(Path.GetTempPath(), $"{Guid.NewGuid():N}.html"); + string tempFilePath = Path.Join(Path.GetTempPath(), $"{Guid.NewGuid():N}.html"); await File.WriteAllTextAsync(tempFilePath, "file-uri", ct); using var windowUtility = InfiniFrameTestWindow.Create(ct); IInfiniFrameWindow window = windowUtility.Window; diff --git a/tests/InfiniTests.InfiniFrame/Window/Features/PageNavigation/TryLoadPathTests.cs b/tests/InfiniTests.InfiniFrame/Window/Features/PageNavigation/TryLoadPathTests.cs index 0ca4ba972..5e00fd99f 100644 --- a/tests/InfiniTests.InfiniFrame/Window/Features/PageNavigation/TryLoadPathTests.cs +++ b/tests/InfiniTests.InfiniFrame/Window/Features/PageNavigation/TryLoadPathTests.cs @@ -13,7 +13,7 @@ public class TryLoadPathTests { [SkipOnLinux] public async Task AtWindowStage_ExistingFilePath_ReturnsTrue(CancellationToken ct) { // Arrange - string tempFilePath = Path.Combine(Path.GetTempPath(), $"{Guid.NewGuid():N}.html"); + string tempFilePath = Path.Join(Path.GetTempPath(), $"{Guid.NewGuid():N}.html"); await File.WriteAllTextAsync(tempFilePath, "try-load-path", ct); using var windowUtility = InfiniFrameTestWindow.Create(ct); IInfiniFrameWindow window = windowUtility.Window; diff --git a/tests/InfiniTests.InfiniFrame/Window/Features/PageNavigation/TryLoadUriTests.cs b/tests/InfiniTests.InfiniFrame/Window/Features/PageNavigation/TryLoadUriTests.cs index f634fe663..ecc3fff91 100644 --- a/tests/InfiniTests.InfiniFrame/Window/Features/PageNavigation/TryLoadUriTests.cs +++ b/tests/InfiniTests.InfiniFrame/Window/Features/PageNavigation/TryLoadUriTests.cs @@ -13,7 +13,7 @@ public class TryLoadUriTests { [SkipOnLinux] public async Task AtWindowStage_FileUri_ReturnsTrue(CancellationToken ct) { // Arrange - string tempFilePath = Path.Combine(Path.GetTempPath(), $"{Guid.NewGuid():N}.html"); + string tempFilePath = Path.Join(Path.GetTempPath(), $"{Guid.NewGuid():N}.html"); await File.WriteAllTextAsync(tempFilePath, "try-load-uri", ct); using var windowUtility = InfiniFrameTestWindow.Create(ct); IInfiniFrameWindow window = windowUtility.Window; diff --git a/tests/TestHost/MacOsTestingPlatformEntryPoint.cs b/tests/TestHost/MacOsTestingPlatformEntryPoint.cs index 7cb8d33f1..e0b0fd90a 100644 --- a/tests/TestHost/MacOsTestingPlatformEntryPoint.cs +++ b/tests/TestHost/MacOsTestingPlatformEntryPoint.cs @@ -87,4 +87,4 @@ private static void AddSelfRegisteredExtensions(ITestApplicationBuilder builder, addExtensions.Invoke(null, [builder, args]); } -} \ No newline at end of file +}