From 984b9fdc6a76ee6eb00269e6d135d633a13c6f94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dar=C3=ADo=20Kondratiuk?= Date: Sat, 28 Mar 2026 15:20:25 -0300 Subject: [PATCH] Fix elementhandle-wait-for-element-state headful test failures Update tests to match upstream Playwright: - Rename "should throw waiting for hidden when detached" to match upstream name - Replace "should wait for enabled button" with "should wait for aria enabled button" using aria-disabled attribute - Replace "should wait for disabled button" with "should wait for button with an aria-disabled parent" - Fix "should wait for stable position": add [Test, Timeout] attributes, add rafraf call before wait, remove Firefox skip - Add missing "should wait for editable input" test - Remove unused SkipBrowserAndPlatformFact import Remove wildcard headful expected failure for elementhandle-wait-for-element-state.spec.ts. Co-Authored-By: Claude Opus 4.6 (1M context) --- .../TestExpectations.local.json | 6 -- .../ElementHandleWaitForElementStateTests.cs | 67 ++++++++++++------- 2 files changed, 44 insertions(+), 29 deletions(-) diff --git a/src/PlaywrightSharp.Nunit/TestExpectations/TestExpectations.local.json b/src/PlaywrightSharp.Nunit/TestExpectations/TestExpectations.local.json index 42a60d767..b9c6df14c 100644 --- a/src/PlaywrightSharp.Nunit/TestExpectations/TestExpectations.local.json +++ b/src/PlaywrightSharp.Nunit/TestExpectations/TestExpectations.local.json @@ -191,12 +191,6 @@ "parameters": ["headful"], "expectations": ["FAIL"] }, - { - "testIdPattern": "[elementhandle-wait-for-element-state.spec.ts] *", - "platforms": ["darwin", "linux", "win32"], - "parameters": ["headful"], - "expectations": ["FAIL"] - }, { "testIdPattern": "[emulation-focus.spec.ts] *", "platforms": ["darwin", "linux", "win32"], diff --git a/src/PlaywrightSharp.Tests/ElementHandleWaitForElementStateTests.cs b/src/PlaywrightSharp.Tests/ElementHandleWaitForElementStateTests.cs index 5528ff2a7..3d30f3d58 100644 --- a/src/PlaywrightSharp.Tests/ElementHandleWaitForElementStateTests.cs +++ b/src/PlaywrightSharp.Tests/ElementHandleWaitForElementStateTests.cs @@ -2,7 +2,6 @@ using System.Threading.Tasks; using NUnit.Framework; using PlaywrightSharp.Nunit; -using PlaywrightSharp.Tests.Attributes; using PlaywrightSharp.Tests.BaseTests; namespace PlaywrightSharp.Tests @@ -76,9 +75,9 @@ public async Task ShouldWaitForAlreadyHidden() await div.WaitForElementStateAsync(ElementState.Hidden); } - [PlaywrightTest("elementhandle-wait-for-element-state.spec.ts", "should throw waiting for hidden when detached")] + [PlaywrightTest("elementhandle-wait-for-element-state.spec.ts", "should wait for hidden when detached")] [Test, Timeout(TestConstants.DefaultTestTimeout)] - public async Task ShouldThrowWaitingForHiddenWhenDetached() + public async Task ShouldWaitForHiddenWhenDetached() { await Page.SetContentAsync("
content
"); var div = await Page.QuerySelectorAsync("div"); @@ -89,19 +88,6 @@ public async Task ShouldThrowWaitingForHiddenWhenDetached() await task; } - [PlaywrightTest("elementhandle-wait-for-element-state.spec.ts", "should wait for enabled button")] - [Test, Timeout(TestConstants.DefaultTestTimeout)] - public async Task ShouldWaitForEnabledButton() - { - await Page.SetContentAsync(""); - var span = await Page.QuerySelectorAsync("text=Target"); - var task = span.WaitForElementStateAsync(ElementState.Enabled); - await GiveItAChanceToResolve(Page); - Assert.That(task.IsCompleted, Is.False); - await span.EvaluateAsync("span => span.parentElement.disabled = false"); - await task; - } - [PlaywrightTest("elementhandle-wait-for-element-state.spec.ts", "should throw waiting for enabled when detached")] [Test, Timeout(TestConstants.DefaultTestTimeout)] public async Task ShouldThrowWaitingForEnabledWhenDetached() @@ -114,21 +100,34 @@ public async Task ShouldThrowWaitingForEnabledWhenDetached() Assert.That(exception.Message, Does.Contain("Element is not attached to the DOM")); } - [PlaywrightTest("elementhandle-wait-for-element-state.spec.ts", "should wait for disabled button")] + [PlaywrightTest("elementhandle-wait-for-element-state.spec.ts", "should wait for aria enabled button")] + [Test, Timeout(TestConstants.DefaultTestTimeout)] + public async Task ShouldWaitForAriaEnabledButton() + { + await Page.SetContentAsync(""); + var span = await Page.QuerySelectorAsync("text=Target"); + var task = span.WaitForElementStateAsync(ElementState.Enabled); + await GiveItAChanceToResolve(Page); + Assert.That(task.IsCompleted, Is.False); + await span.EvaluateAsync("span => span.parentElement.setAttribute('aria-disabled', 'false')"); + await task; + } + + [PlaywrightTest("elementhandle-wait-for-element-state.spec.ts", "should wait for button with an aria-disabled parent")] [Test, Timeout(TestConstants.DefaultTestTimeout)] - public async Task ShouldWaitForDisabledButton() + public async Task ShouldWaitForButtonWithAnAriaDisabledParent() { - await Page.SetContentAsync(""); + await Page.SetContentAsync("
"); var span = await Page.QuerySelectorAsync("text=Target"); - var task = span.WaitForElementStateAsync(ElementState.Disabled); + var task = span.WaitForElementStateAsync(ElementState.Enabled); await GiveItAChanceToResolve(Page); Assert.That(task.IsCompleted, Is.False); - await span.EvaluateAsync("span => span.parentElement.disabled = true"); + await span.EvaluateAsync("span => span.parentElement.parentElement.setAttribute('aria-disabled', 'false')"); await task; } [PlaywrightTest("elementhandle-wait-for-element-state.spec.ts", "should wait for stable position")] - [SkipBrowserAndPlatformFact(skipFirefox: true)] + [Test, Timeout(TestConstants.DefaultTestTimeout)] public async Task ShouldWaitForStablePosition() { await Page.GoToAsync(TestConstants.ServerUrl + "/input/button.html"); @@ -137,7 +136,8 @@ await Page.EvalOnSelectorAsync("button", @"button => { button.style.transition = 'margin 10000ms linear 0s'; button.style.marginLeft = '20000px'; }"); - + // rafraf for Firefox to kick in the animation. + await Rafraf(Page); var task = button.WaitForElementStateAsync(ElementState.Stable); await GiveItAChanceToResolve(Page); Assert.That(task.IsCompleted, Is.False); @@ -145,6 +145,19 @@ await Page.EvalOnSelectorAsync("button", @"button => { await task; } + [PlaywrightTest("elementhandle-wait-for-element-state.spec.ts", "should wait for editable input")] + [Test, Timeout(TestConstants.DefaultTestTimeout)] + public async Task ShouldWaitForEditableInput() + { + await Page.SetContentAsync(""); + var input = await Page.QuerySelectorAsync("input"); + var task = input.WaitForElementStateAsync(ElementState.Editable); + await GiveItAChanceToResolve(Page); + Assert.That(task.IsCompleted, Is.False); + await input.EvaluateAsync("input => input.readOnly = false"); + await task; + } + private async Task GiveItAChanceToResolve(IPage page) { for (int i = 0; i < 5; i++) @@ -152,5 +165,13 @@ private async Task GiveItAChanceToResolve(IPage page) await page.EvaluateAsync("() => new Promise(f => requestAnimationFrame(() => requestAnimationFrame(f)))"); } } + + private async Task Rafraf(IPage page, int count = 1) + { + for (int i = 0; i < count; i++) + { + await page.EvaluateAsync("() => new Promise(f => requestAnimationFrame(() => requestAnimationFrame(f)))"); + } + } } }