From 06ec302fd87e66fffdff0315d27d2906ca8fe29d Mon Sep 17 00:00:00 2001 From: Dmitry Gozman Date: Fri, 1 May 2026 14:48:26 +0100 Subject: [PATCH] feat(page): make IPage implement IAsyncDisposable Mirrors IBrowserContext / IBrowser so that `await using` works on a Page. DisposeAsync delegates to CloseAsync. Fixes https://github.com/microsoft/playwright-dotnet/issues/3243 --- src/Playwright.Tests/PageCloseTests.cs | 11 +++++++++++ src/Playwright/API/Supplements/IPage.cs | 2 +- src/Playwright/Core/Page.cs | 3 +++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/Playwright.Tests/PageCloseTests.cs b/src/Playwright.Tests/PageCloseTests.cs index a2c955df5d..cc2e9c96dd 100644 --- a/src/Playwright.Tests/PageCloseTests.cs +++ b/src/Playwright.Tests/PageCloseTests.cs @@ -26,4 +26,15 @@ namespace Microsoft.Playwright.Tests; public class PageCloseTests : PageTestEx { + [PlaywrightTest("page-close.spec.ts", "should close the page using await using")] + public async Task ShouldClosePageWithAwaitUsing() + { + IPage closedPage; + await using (var page = await Context.NewPageAsync()) + { + closedPage = page; + Assert.False(page.IsClosed); + } + Assert.True(closedPage.IsClosed); + } } diff --git a/src/Playwright/API/Supplements/IPage.cs b/src/Playwright/API/Supplements/IPage.cs index 7d8a44bc6b..5e3e34fd23 100644 --- a/src/Playwright/API/Supplements/IPage.cs +++ b/src/Playwright/API/Supplements/IPage.cs @@ -29,7 +29,7 @@ namespace Microsoft.Playwright; -public partial interface IPage +public partial interface IPage : IAsyncDisposable { Task EvaluateAsync(string expression, object? arg = default); diff --git a/src/Playwright/Core/Page.cs b/src/Playwright/Core/Page.cs index 36b895952c..df4dc2bf89 100644 --- a/src/Playwright/Core/Page.cs +++ b/src/Playwright/Core/Page.cs @@ -500,6 +500,9 @@ internal async Task InnerWaitForEventAsync(PlaywrightEvent pageEvent, F return await waitForEventTask.ConfigureAwait(false); } + [MethodImpl(MethodImplOptions.NoInlining)] + public ValueTask DisposeAsync() => new(CloseAsync()); + [MethodImpl(MethodImplOptions.NoInlining)] public async Task CloseAsync(PageCloseOptions? options = default) {