From a17e059baa89dca9c329d669caa12d6a74a7a24d Mon Sep 17 00:00:00 2001 From: arnonax-tr Date: Wed, 6 Aug 2025 11:12:15 +0300 Subject: [PATCH 1/2] Handle different types of results in ExecuteScript --- .../Tests.cs | 56 +++++++++++++++++++ ....Selenium.PlaywrightWebDriver.Tests.csproj | 4 +- .../PlaywrightWebDriver.cs | 23 +++++++- 3 files changed, 80 insertions(+), 3 deletions(-) diff --git a/TomLonghurst.Selenium.PlaywrightWebDriver.Tests/Tests.cs b/TomLonghurst.Selenium.PlaywrightWebDriver.Tests/Tests.cs index fe1d889..73200e8 100644 --- a/TomLonghurst.Selenium.PlaywrightWebDriver.Tests/Tests.cs +++ b/TomLonghurst.Selenium.PlaywrightWebDriver.Tests/Tests.cs @@ -74,6 +74,62 @@ public async Task Script_With_Element_Argument() Console.WriteLine(); } + [TestCase("5", 5L)] + [TestCase("'foo'", "foo")] + [TestCase("false", false)] + [TestCase("true", true)] + [TestCase("1.5", 1.5d)] + [TestCase("null", null)] + public async Task Script_With_Primitive_Return_Value(string script, object? expectedValue) + { + await using var driver = await PlaywrightWebDriver.CreateAsync(); + + var result = driver.ExecuteScript(script); + + Assert.That(result, Is.EqualTo(expectedValue)); + } + + [Test] + public async Task Script_With_Array_Return_Value() + { + await using var driver = await PlaywrightWebDriver.CreateAsync(); + + var result = driver.ExecuteScript("[1, '2', 3]"); + + Assert.That(result, Is.EqualTo(new object[] {1, "2", 3})); + } + + [Test, Ignore("Doesn't work. It throws Microsoft.Playwright.PlaywrightException : SyntaxError: Unexpected token ':'. , though with Selenium ChromeDriver the same script works just fine.")] + public async Task Script_With_Object_Return_Value() + { + await using var driver = await PlaywrightWebDriver.CreateAsync(); + + var result = driver.ExecuteScript("return {a: 5, b:'foo'}"); + + Assert.That(result, Is.InstanceOf>()); + var dict = (Dictionary)result; + using (Assert.EnterMultipleScope()) + { + Assert.That(dict["a"], Is.EqualTo(5L)); + Assert.That(dict["b"], Is.EqualTo("foo")); + } + } + + [Test, Ignore("Doesn't work. Result is 'ValueKind = String : \"ref: \"', but doesn't contain the actual reference to the element. This does work with ChromeDriver though.")] + public async Task Script_With_Element_Return_Value() + { + await using var driver = await PlaywrightWebDriver.CreateAsync(); + + driver.Url = "file://" + Path.Combine(Environment.CurrentDirectory, "HtmlPages", "LocatorsTest.html"); + + var idElement = driver.FindElement(By.Id("id1")); + var result = driver.ExecuteScript("return arguments[0]", idElement); + + Assert.That(result, Is.AssignableFrom()); + var returnedElement = (IWebElement)result; + Assert.That(returnedElement.Text, Is.EqualTo("Id One")); + } + [Test] public async Task Locators_Test() { diff --git a/TomLonghurst.Selenium.PlaywrightWebDriver.Tests/TomLonghurst.Selenium.PlaywrightWebDriver.Tests.csproj b/TomLonghurst.Selenium.PlaywrightWebDriver.Tests/TomLonghurst.Selenium.PlaywrightWebDriver.Tests.csproj index 56b5e33..69c0765 100644 --- a/TomLonghurst.Selenium.PlaywrightWebDriver.Tests/TomLonghurst.Selenium.PlaywrightWebDriver.Tests.csproj +++ b/TomLonghurst.Selenium.PlaywrightWebDriver.Tests/TomLonghurst.Selenium.PlaywrightWebDriver.Tests.csproj @@ -1,7 +1,7 @@ - + - net6.0 + net8.0 enable enable diff --git a/TomLonghurst.Selenium.PlaywrightWebDriver/PlaywrightWebDriver.cs b/TomLonghurst.Selenium.PlaywrightWebDriver/PlaywrightWebDriver.cs index d160821..a2166bb 100644 --- a/TomLonghurst.Selenium.PlaywrightWebDriver/PlaywrightWebDriver.cs +++ b/TomLonghurst.Selenium.PlaywrightWebDriver/PlaywrightWebDriver.cs @@ -3,6 +3,7 @@ using System.Collections.ObjectModel; using System.Linq; using System.Runtime.CompilerServices; +using System.Text.Json; using System.Text.RegularExpressions; using System.Threading.Tasks; using Microsoft.Playwright; @@ -231,7 +232,27 @@ public string Url return CurrentFrameLocators.Last().Owner.EvaluateAsync(script, args).Synchronously(); } - return CurrentPage.EvaluateAsync(script, args).Synchronously(); + var playwrightResult = CurrentPage.EvaluateAsync(script, args).Synchronously(); + return ConvertResult(playwrightResult); + } + + private static object? ConvertResult(JsonElement? playwrightResult) + { + if (playwrightResult == null) + { + return null; + } + + var value = playwrightResult.Value; + return value.ValueKind switch + { + JsonValueKind.False => false, + JsonValueKind.True => true, + JsonValueKind.Number => value.TryGetInt64(out var intValue) ? intValue : value.GetDouble(), + JsonValueKind.String => value.GetString(), + JsonValueKind.Array => value.EnumerateArray().Select(x => ConvertResult(x)).ToArray(), + _ => value + }; } #if SeleniumVersion_4 From 40544476f70609b03f821fe3b3c5e09c2dee30c2 Mon Sep 17 00:00:00 2001 From: arnonax-tr Date: Wed, 6 Aug 2025 11:30:48 +0300 Subject: [PATCH 2/2] Fix also when CurrentFrameLocators is not empty. --- .../PlaywrightWebDriver.cs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/TomLonghurst.Selenium.PlaywrightWebDriver/PlaywrightWebDriver.cs b/TomLonghurst.Selenium.PlaywrightWebDriver/PlaywrightWebDriver.cs index a2166bb..0f249b4 100644 --- a/TomLonghurst.Selenium.PlaywrightWebDriver/PlaywrightWebDriver.cs +++ b/TomLonghurst.Selenium.PlaywrightWebDriver/PlaywrightWebDriver.cs @@ -226,13 +226,11 @@ public string Url public object? ExecuteScript(string script, params object[] args) { script = ConvertScript(script, args); - - if (CurrentFrameLocators.Any()) - { - return CurrentFrameLocators.Last().Owner.EvaluateAsync(script, args).Synchronously(); - } - - var playwrightResult = CurrentPage.EvaluateAsync(script, args).Synchronously(); + + var playwrightResult = CurrentFrameLocators.Any() + ? CurrentFrameLocators.Last().Owner.EvaluateAsync(script, args).Synchronously() + : CurrentPage.EvaluateAsync(script, args).Synchronously(); + return ConvertResult(playwrightResult); }