diff --git a/README.md b/README.md index 8868f959d3..69a4b1a419 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ | | Linux | macOS | Windows | | :--- | :---: | :---: | :---: | -| Chromium 128.0.6613.7 | ✅ | ✅ | ✅ | +| Chromium 128.0.6613.18 | ✅ | ✅ | ✅ | | WebKit 18.0 | ✅ | ✅ | ✅ | | Firefox 128.0 | ✅ | ✅ | ✅ | diff --git a/src/Common/Version.props b/src/Common/Version.props index bc6778ef62..13f46bd77c 100644 --- a/src/Common/Version.props +++ b/src/Common/Version.props @@ -2,7 +2,7 @@ 1.45.0 $(AssemblyVersion) - 1.46.0-beta-1722359450000 + 1.46.0-beta-1722491095000 $(AssemblyVersion) $(AssemblyVersion) true diff --git a/src/Playwright.Tests/PageEvaluateTests.cs b/src/Playwright.Tests/PageEvaluateTests.cs index aa74532a03..9fafc56364 100644 --- a/src/Playwright.Tests/PageEvaluateTests.cs +++ b/src/Playwright.Tests/PageEvaluateTests.cs @@ -547,24 +547,62 @@ public async Task ShouldNotLeakHandles() } [PlaywrightTest("page-evaluate.spec.ts", "should evaluate exception with a function on the stack")] - [Ignore("todo https://github.com/microsoft/playwright-dotnet/issues/2947")] public async Task ShouldEvaluateExceptionWithAFunctionOnTheStack() { - var exception = await Page.EvaluateAsync(@"() => { + var exception = await Page.EvaluateAsync(@"() => { return (function functionOnStack() { return new Error('error message'); })(); }"); - Assert.Equals("error message", exception.Message); - StringAssert.Contains("functionOnStack", exception.StackTrace); + StringAssert.Contains("Error: error message", exception.Message); + StringAssert.Contains("functionOnStack", exception.Message); } [PlaywrightTest("page-evaluate.spec.ts", "should evaluate exception")] - [Ignore("todo https://github.com/microsoft/playwright-dotnet/issues/2947")] public async Task ShouldEvaluateException() { - string exception = await Page.EvaluateAsync(@"() => new Error('error message')"); - StringAssert.Contains("Error: error message", exception); + var exception = await Page.EvaluateAsync(@"() => { + function innerFunction() { + const e = new Error('error message'); + e.name = 'foobar'; + return e; + } + return innerFunction(); + }"); + Assert.IsInstanceOf(exception); + StringAssert.Contains("foobar: error message", (exception as Exception).Message); + StringAssert.Contains("innerFunction", (exception as Exception).Message); + StringAssert.Contains("foobar: error message", exception.ToString()); + } + + [PlaywrightTest("page-evaluate.spec.ts", "should pass exception argument")] + public async Task ShouldPassExceptionArgument() + { + Exception InnerFunction() + { + try + { + // We need to throw so a stack gets assigned + throw new PlaywrightException("error message"); + } + catch (Exception e) + { + return e; + } + } + var exception = await Page.EvaluateAsync(@"e => { + return { message: e.message, name: e.name, stack: e.stack }; + }", InnerFunction()); + StringAssert.Contains("error message", exception.Message); + StringAssert.Contains("PlaywrightException: error message", exception.Stack); + Assert.AreEqual("PlaywrightException", exception.Name); + } + + public struct ErrorStruct + { + public string Message { get; set; } + public string Name { get; set; } + public string Stack { get; set; } } [PlaywrightTest("page-evaluate.spec.ts", "should evaluate date")] diff --git a/src/Playwright/Transport/Converters/EvaluateArgumentValueConverter.cs b/src/Playwright/Transport/Converters/EvaluateArgumentValueConverter.cs index 512ea0f155..aed915e39a 100644 --- a/src/Playwright/Transport/Converters/EvaluateArgumentValueConverter.cs +++ b/src/Playwright/Transport/Converters/EvaluateArgumentValueConverter.cs @@ -123,6 +123,19 @@ internal static object Serialize(object value, List return new { bi = bigInteger.ToString(CultureInfo.InvariantCulture) }; } + if (value is Exception exception) + { + return new Dictionary + { + ["e"] = new Dictionary + { + ["n"] = exception.GetType().Name, + ["m"] = exception.Message, + ["s"] = exception.StackTrace ?? string.Empty, + }, + }; + } + if (value is Regex regex) { return new { r = new { p = regex.ToString(), f = regex.Options.GetInlineFlags() } }; @@ -330,6 +343,11 @@ private static object ParseEvaluateResultToExpando(JsonElement result, IDictiona return BigInteger.Parse(bigInt.ToObject(), CultureInfo.InvariantCulture); } + if (result.TryGetProperty("e", out var error)) + { + return new Exception(error.GetProperty("s").ToString()); + } + if (result.TryGetProperty("r", out var regex)) { return new Regex(regex.GetProperty("p").ToString(), RegexOptionsExtensions.FromInlineFlags(regex.GetProperty("f").ToString()));