[wasm][debugger][tests] Add some async stepping tests (#42461)
authorAnkit Jain <radical@gmail.com>
Tue, 22 Sep 2020 05:36:56 +0000 (01:36 -0400)
committerGitHub <noreply@github.com>
Tue, 22 Sep 2020 05:36:56 +0000 (01:36 -0400)
* [wasm][debugger][tests] Move stepping tests to a separate file

* [wasm][debugger][tests] Add more async stepping tests, some of which are

.. failing.

src/mono/wasm/debugger/DebuggerTestSuite/SteppingTests.cs [new file with mode: 0644]
src/mono/wasm/debugger/DebuggerTestSuite/Support.cs
src/mono/wasm/debugger/DebuggerTestSuite/Tests.cs
src/mono/wasm/debugger/tests/debugger-async-step.cs [deleted file]
src/mono/wasm/debugger/tests/debugger-test/debugger-async-step.cs [new file with mode: 0644]
src/mono/wasm/debugger/tests/debugger-test/debugger-driver.html

diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/SteppingTests.cs b/src/mono/wasm/debugger/DebuggerTestSuite/SteppingTests.cs
new file mode 100644 (file)
index 0000000..16cfe82
--- /dev/null
@@ -0,0 +1,1005 @@
+using System;
+using System.Linq;
+using System.Threading.Tasks;
+using Newtonsoft.Json.Linq;
+using Xunit;
+
+namespace DebuggerTests
+{
+    public class SteppingTests : DebuggerTestBase
+    {
+        [Fact]
+        public async Task TrivalStepping()
+        {
+            var insp = new Inspector();
+            //Collect events
+            var scripts = SubscribeToScripts(insp);
+
+            await Ready();
+            await insp.Ready(async (cli, token) =>
+            {
+                ctx = new DebugTestContext(cli, insp, token, scripts);
+
+                var bp = await SetBreakpoint("dotnet://debugger-test.dll/debugger-test.cs", 10, 8);
+
+                await EvaluateAndCheck(
+                    "window.setTimeout(function() { invoke_add(); }, 1);",
+                    "dotnet://debugger-test.dll/debugger-test.cs", 10, 8,
+                    "IntAdd",
+                    wait_for_event_fn: (pause_location) =>
+                    {
+                        //make sure we're on the right bp
+                        Assert.Equal(bp.Value["breakpointId"]?.ToString(), pause_location["hitBreakpoints"]?[0]?.Value<string>());
+
+                        var top_frame = pause_location["callFrames"][0];
+                        CheckLocation("dotnet://debugger-test.dll/debugger-test.cs", 8, 4, scripts, top_frame["functionLocation"]);
+                        return Task.CompletedTask;
+                    }
+                );
+
+                await StepAndCheck(StepKind.Over, "dotnet://debugger-test.dll/debugger-test.cs", 11, 8, "IntAdd",
+                    wait_for_event_fn: (pause_location) =>
+                    {
+                        var top_frame = pause_location["callFrames"][0];
+                        CheckLocation("dotnet://debugger-test.dll/debugger-test.cs", 8, 4, scripts, top_frame["functionLocation"]);
+                        return Task.CompletedTask;
+                    }
+                );
+            });
+        }
+
+        [Fact]
+        public async Task InspectLocalsDuringStepping()
+        {
+            var insp = new Inspector();
+            //Collect events
+            var scripts = SubscribeToScripts(insp);
+
+            await Ready();
+            await insp.Ready(async (cli, token) =>
+            {
+                ctx = new DebugTestContext(cli, insp, token, scripts);
+
+                var debugger_test_loc = "dotnet://debugger-test.dll/debugger-test.cs";
+                await SetBreakpoint(debugger_test_loc, 10, 8);
+
+                await EvaluateAndCheck(
+                    "window.setTimeout(function() { invoke_add(); }, 1);",
+                    debugger_test_loc, 10, 8, "IntAdd",
+                    locals_fn: (locals) =>
+                    {
+                        CheckNumber(locals, "a", 10);
+                        CheckNumber(locals, "b", 20);
+                        CheckNumber(locals, "c", 30);
+                        CheckNumber(locals, "d", 0);
+                        CheckNumber(locals, "e", 0);
+                    }
+                );
+
+                await StepAndCheck(StepKind.Over, debugger_test_loc, 11, 8, "IntAdd",
+                    locals_fn: (locals) =>
+                    {
+                        CheckNumber(locals, "a", 10);
+                        CheckNumber(locals, "b", 20);
+                        CheckNumber(locals, "c", 30);
+                        CheckNumber(locals, "d", 50);
+                        CheckNumber(locals, "e", 0);
+                    }
+                );
+
+                //step and get locals
+                await StepAndCheck(StepKind.Over, debugger_test_loc, 12, 8, "IntAdd",
+                    locals_fn: (locals) =>
+                    {
+                        CheckNumber(locals, "a", 10);
+                        CheckNumber(locals, "b", 20);
+                        CheckNumber(locals, "c", 30);
+                        CheckNumber(locals, "d", 50);
+                        CheckNumber(locals, "e", 60);
+                    }
+                );
+            });
+        }
+
+        [Theory]
+        [InlineData(false)]
+        [InlineData(true)]
+        public async Task InspectLocalsInPreviousFramesDuringSteppingIn2(bool use_cfo)
+        {
+            var insp = new Inspector();
+            //Collect events
+            var scripts = SubscribeToScripts(insp);
+
+            await Ready();
+            await insp.Ready(async (cli, token) =>
+            {
+                ctx = new DebugTestContext(cli, insp, token, scripts);
+                ctx.UseCallFunctionOnBeforeGetProperties = use_cfo;
+
+                var dep_cs_loc = "dotnet://debugger-test.dll/dependency.cs";
+                await SetBreakpoint(dep_cs_loc, 33, 8);
+
+                var debugger_test_loc = "dotnet://debugger-test.dll/debugger-test.cs";
+
+                // Will stop in Complex.DoEvenMoreStuff
+                var pause_location = await EvaluateAndCheck(
+                    "window.setTimeout(function() { invoke_use_complex (); }, 1);",
+                    dep_cs_loc, 33, 8, "DoEvenMoreStuff",
+                    locals_fn: (locals) =>
+                    {
+                        Assert.Single(locals);
+                        CheckObject(locals, "this", "Simple.Complex");
+                    }
+                );
+
+                var props = await GetObjectOnFrame(pause_location["callFrames"][0], "this");
+                Assert.Equal(3, props.Count());
+                CheckNumber(props, "A", 10);
+                CheckString(props, "B", "xx");
+                CheckString(props, "c", "20_xx");
+
+                // Check UseComplex frame
+                var locals_m1 = await GetLocalsForFrame(pause_location["callFrames"][3], debugger_test_loc, 23, 8, "UseComplex");
+                Assert.Equal(7, locals_m1.Count());
+
+                CheckNumber(locals_m1, "a", 10);
+                CheckNumber(locals_m1, "b", 20);
+                CheckObject(locals_m1, "complex", "Simple.Complex");
+                CheckNumber(locals_m1, "c", 30);
+                CheckNumber(locals_m1, "d", 50);
+                CheckNumber(locals_m1, "e", 60);
+                CheckNumber(locals_m1, "f", 0);
+
+                props = await GetObjectOnFrame(pause_location["callFrames"][3], "complex");
+                Assert.Equal(3, props.Count());
+                CheckNumber(props, "A", 10);
+                CheckString(props, "B", "xx");
+                CheckString(props, "c", "20_xx");
+
+                pause_location = await StepAndCheck(StepKind.Over, dep_cs_loc, 23, 8, "DoStuff", times: 2);
+                // Check UseComplex frame again
+                locals_m1 = await GetLocalsForFrame(pause_location["callFrames"][1], debugger_test_loc, 23, 8, "UseComplex");
+                Assert.Equal(7, locals_m1.Count());
+
+                CheckNumber(locals_m1, "a", 10);
+                CheckNumber(locals_m1, "b", 20);
+                CheckObject(locals_m1, "complex", "Simple.Complex");
+                CheckNumber(locals_m1, "c", 30);
+                CheckNumber(locals_m1, "d", 50);
+                CheckNumber(locals_m1, "e", 60);
+                CheckNumber(locals_m1, "f", 0);
+
+                props = await GetObjectOnFrame(pause_location["callFrames"][1], "complex");
+                Assert.Equal(3, props.Count());
+                CheckNumber(props, "A", 10);
+                CheckString(props, "B", "xx");
+                CheckString(props, "c", "20_xx");
+            });
+        }
+
+        [Theory]
+        [InlineData(false)]
+        [InlineData(true)]
+        public async Task InspectLocalsInPreviousFramesDuringSteppingIn(bool use_cfo)
+        {
+            var insp = new Inspector();
+            //Collect events
+            var scripts = SubscribeToScripts(insp);
+
+            await Ready();
+            await insp.Ready(async (cli, token) =>
+            {
+                ctx = new DebugTestContext(cli, insp, token, scripts);
+                ctx.UseCallFunctionOnBeforeGetProperties = use_cfo;
+
+                var debugger_test_loc = "dotnet://debugger-test.dll/debugger-test.cs";
+                await SetBreakpoint(debugger_test_loc, 111, 12);
+
+                // Will stop in InnerMethod
+                var wait_res = await EvaluateAndCheck(
+                    "window.setTimeout(function() { invoke_outer_method(); }, 1);",
+                    debugger_test_loc, 111, 12, "InnerMethod",
+                    locals_fn: (locals) =>
+                    {
+                        Assert.Equal(4, locals.Count());
+                        CheckNumber(locals, "i", 5);
+                        CheckNumber(locals, "j", 24);
+                        CheckString(locals, "foo_str", "foo");
+                        CheckObject(locals, "this", "Math.NestedInMath");
+                    }
+                );
+
+                var this_props = await GetObjectOnFrame(wait_res["callFrames"][0], "this");
+                Assert.Equal(2, this_props.Count());
+                CheckObject(this_props, "m", "Math");
+                CheckValueType(this_props, "SimpleStructProperty", "Math.SimpleStruct");
+
+                var ss_props = await GetObjectOnLocals(this_props, "SimpleStructProperty");
+                var dt = new DateTime(2020, 1, 2, 3, 4, 5);
+                await CheckProps(ss_props, new
+                {
+                    dt = TDateTime(dt),
+                    gs = TValueType("Math.GenericStruct<System.DateTime>")
+                }, "ss_props");
+
+                // Check OuterMethod frame
+                var locals_m1 = await GetLocalsForFrame(wait_res["callFrames"][1], debugger_test_loc, 87, 8, "OuterMethod");
+                Assert.Equal(5, locals_m1.Count());
+                // FIXME: Failing test CheckNumber (locals_m1, "i", 5);
+                // FIXME: Failing test CheckString (locals_m1, "text", "Hello");
+                CheckNumber(locals_m1, "new_i", 0);
+                CheckNumber(locals_m1, "k", 0);
+                CheckObject(locals_m1, "nim", "Math.NestedInMath");
+
+                // step back into OuterMethod
+                await StepAndCheck(StepKind.Over, debugger_test_loc, 91, 8, "OuterMethod", times: 9,
+                    locals_fn: (locals) =>
+                    {
+                        Assert.Equal(5, locals.Count());
+
+                        // FIXME: Failing test CheckNumber (locals_m1, "i", 5);
+                        CheckString(locals, "text", "Hello");
+                        // FIXME: Failing test CheckNumber (locals, "new_i", 24);
+                        CheckNumber(locals, "k", 19);
+                        CheckObject(locals, "nim", "Math.NestedInMath");
+                    }
+                );
+
+                //await StepAndCheck (StepKind.Over, "dotnet://debugger-test.dll/debugger-test.cs", 81, 2, "OuterMethod", times: 2);
+
+                // step into InnerMethod2
+                await StepAndCheck(StepKind.Into, "dotnet://debugger-test.dll/debugger-test.cs", 96, 4, "InnerMethod2",
+                    locals_fn: (locals) =>
+                    {
+                        Assert.Equal(3, locals.Count());
+
+                        CheckString(locals, "s", "test string");
+                        //out var: CheckNumber (locals, "k", 0);
+                        CheckNumber(locals, "i", 24);
+                    }
+                );
+
+                await StepAndCheck(StepKind.Over, "dotnet://debugger-test.dll/debugger-test.cs", 100, 4, "InnerMethod2", times: 4,
+                    locals_fn: (locals) =>
+                    {
+                        Assert.Equal(3, locals.Count());
+
+                        CheckString(locals, "s", "test string");
+                        // FIXME: Failing test CheckNumber (locals, "k", 34);
+                        CheckNumber(locals, "i", 24);
+                    }
+                );
+
+                await StepAndCheck(StepKind.Over, "dotnet://debugger-test.dll/debugger-test.cs", 92, 8, "OuterMethod", times: 2,
+                    locals_fn: (locals) =>
+                    {
+                        Assert.Equal(5, locals.Count());
+
+                        CheckString(locals, "text", "Hello");
+                        // FIXME: failing test CheckNumber (locals, "i", 5);
+                        CheckNumber(locals, "new_i", 22);
+                        CheckNumber(locals, "k", 34);
+                        CheckObject(locals, "nim", "Math.NestedInMath");
+                    }
+                );
+            });
+        }
+
+        [Fact]
+        public async Task InspectLocalsDuringSteppingIn()
+        {
+            var insp = new Inspector();
+            //Collect events
+            var scripts = SubscribeToScripts(insp);
+
+            await Ready();
+            await insp.Ready(async (cli, token) =>
+            {
+                ctx = new DebugTestContext(cli, insp, token, scripts);
+
+                await SetBreakpoint("dotnet://debugger-test.dll/debugger-test.cs", 86, 8);
+
+                await EvaluateAndCheck("window.setTimeout(function() { invoke_outer_method(); }, 1);",
+                    "dotnet://debugger-test.dll/debugger-test.cs", 86, 8, "OuterMethod",
+                    locals_fn: (locals) =>
+                    {
+                        Assert.Equal(5, locals.Count());
+
+                        CheckObject(locals, "nim", "Math.NestedInMath");
+                        CheckNumber(locals, "i", 5);
+                        CheckNumber(locals, "k", 0);
+                        CheckNumber(locals, "new_i", 0);
+                        CheckString(locals, "text", null);
+                    }
+                );
+
+                await StepAndCheck(StepKind.Over, "dotnet://debugger-test.dll/debugger-test.cs", 87, 8, "OuterMethod",
+                    locals_fn: (locals) =>
+                    {
+                        Assert.Equal(5, locals.Count());
+
+                        CheckObject(locals, "nim", "Math.NestedInMath");
+                        // FIXME: Failing test CheckNumber (locals, "i", 5);
+                        CheckNumber(locals, "k", 0);
+                        CheckNumber(locals, "new_i", 0);
+                        CheckString(locals, "text", "Hello");
+                    }
+                );
+
+                // Step into InnerMethod
+                await StepAndCheck(StepKind.Into, "dotnet://debugger-test.dll/debugger-test.cs", 105, 8, "InnerMethod");
+                await StepAndCheck(StepKind.Over, "dotnet://debugger-test.dll/debugger-test.cs", 109, 12, "InnerMethod", times: 5,
+                    locals_fn: (locals) =>
+                    {
+                        Assert.Equal(4, locals.Count());
+
+                        CheckNumber(locals, "i", 5);
+                        CheckNumber(locals, "j", 15);
+                        CheckString(locals, "foo_str", "foo");
+                        CheckObject(locals, "this", "Math.NestedInMath");
+                    }
+                );
+
+                // Step back to OuterMethod
+                await StepAndCheck(StepKind.Over, "dotnet://debugger-test.dll/debugger-test.cs", 88, 8, "OuterMethod", times: 6,
+                    locals_fn: (locals) =>
+                    {
+                        Assert.Equal(5, locals.Count());
+
+                        CheckObject(locals, "nim", "Math.NestedInMath");
+                        // FIXME: Failing test CheckNumber (locals, "i", 5);
+                        CheckNumber(locals, "k", 0);
+                        CheckNumber(locals, "new_i", 24);
+                        CheckString(locals, "text", "Hello");
+                    }
+                );
+            });
+        }
+
+        [Theory]
+        [InlineData(false)]
+        [InlineData(true)]
+        public async Task InspectLocalsInAsyncMethods(bool use_cfo)
+        {
+            var insp = new Inspector();
+            //Collect events
+            var scripts = SubscribeToScripts(insp);
+
+            await Ready();
+            await insp.Ready(async (cli, token) =>
+            {
+                ctx = new DebugTestContext(cli, insp, token, scripts);
+                ctx.UseCallFunctionOnBeforeGetProperties = use_cfo;
+                var debugger_test_loc = "dotnet://debugger-test.dll/debugger-test.cs";
+
+                await SetBreakpoint(debugger_test_loc, 120, 12);
+                await SetBreakpoint(debugger_test_loc, 135, 12);
+
+                // Will stop in Asyncmethod0
+                var wait_res = await EvaluateAndCheck(
+                    "window.setTimeout(function() { invoke_async_method_with_await(); }, 1);",
+                    debugger_test_loc, 120, 12, "MoveNext", //FIXME:
+                    locals_fn: (locals) =>
+                    {
+                        Assert.Equal(4, locals.Count());
+                        CheckString(locals, "s", "string from js");
+                        CheckNumber(locals, "i", 42);
+                        CheckString(locals, "local0", "value0");
+                        CheckObject(locals, "this", "Math.NestedInMath");
+                    }
+                );
+                Console.WriteLine(wait_res);
+
+#if false // Disabled for now, as we don't have proper async traces
+                var locals = await GetProperties(wait_res["callFrames"][2]["callFrameId"].Value<string>());
+                Assert.Equal(4, locals.Count());
+                CheckString(locals, "ls", "string from jstest");
+                CheckNumber(locals, "li", 52);
+#endif
+
+                // TODO: previous frames have async machinery details, so no point checking that right now
+
+                var pause_loc = await SendCommandAndCheck(null, "Debugger.resume", debugger_test_loc, 135, 12, /*FIXME: "AsyncMethodNoReturn"*/ "MoveNext",
+                    locals_fn: (locals) =>
+                    {
+                        Assert.Equal(4, locals.Count());
+                        CheckString(locals, "str", "AsyncMethodNoReturn's local");
+                        CheckObject(locals, "this", "Math.NestedInMath");
+                        //FIXME: check fields
+                        CheckValueType(locals, "ss", "Math.SimpleStruct");
+                        CheckArray(locals, "ss_arr", "Math.SimpleStruct[]", 0);
+                        // TODO: struct fields
+                    }
+                );
+
+                var this_props = await GetObjectOnFrame(pause_loc["callFrames"][0], "this");
+                Assert.Equal(2, this_props.Count());
+                CheckObject(this_props, "m", "Math");
+                CheckValueType(this_props, "SimpleStructProperty", "Math.SimpleStruct");
+
+                // TODO: Check `this` properties
+            });
+        }
+
+        [Theory]
+        [InlineData(false)]
+        [InlineData(true)]
+        public async Task InspectValueTypeMethodArgsWhileStepping(bool use_cfo)
+        {
+            var insp = new Inspector();
+            //Collect events
+            var scripts = SubscribeToScripts(insp);
+
+            await Ready();
+            await insp.Ready(async (cli, token) =>
+            {
+                ctx = new DebugTestContext(cli, insp, token, scripts);
+                ctx.UseCallFunctionOnBeforeGetProperties = use_cfo;
+                var debugger_test_loc = "dotnet://debugger-test.dll/debugger-valuetypes-test.cs";
+
+                await SetBreakpoint(debugger_test_loc, 36, 12);
+
+                var pause_location = await EvaluateAndCheck(
+                    "window.setTimeout(function() { invoke_static_method ('[debugger-test] DebuggerTests.ValueTypesTest:TestStructsAsMethodArgs'); }, 1);",
+                    debugger_test_loc, 36, 12, "MethodWithStructArgs");
+                var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value<string>());
+                {
+                    Assert.Equal(3, locals.Count());
+                    CheckString(locals, "label", "TestStructsAsMethodArgs#label");
+                    CheckValueType(locals, "ss_arg", "DebuggerTests.ValueTypesTest.SimpleStruct");
+                    CheckNumber(locals, "x", 3);
+                }
+
+                var dt = new DateTime(2025, 6, 7, 8, 10, 11);
+                var ss_local_as_ss_arg = new
+                {
+                    V = TGetter("V"),
+                    str_member = TString("ss_local#SimpleStruct#string#0#SimpleStruct#str_member"),
+                    dt = TDateTime(dt),
+                    gs = TValueType("DebuggerTests.ValueTypesTest.GenericStruct<System.DateTime>"),
+                    Kind = TEnum("System.DateTimeKind", "Local")
+                };
+                var ss_local_gs = new
+                {
+                    StringField = TString("ss_local#SimpleStruct#string#0#SimpleStruct#gs#StringField"),
+                    List = TObject("System.Collections.Generic.List<System.DateTime>"),
+                    Options = TEnum("DebuggerTests.Options", "Option1")
+                };
+
+                // Check ss_arg's properties
+                var ss_arg_props = await GetObjectOnFrame(pause_location["callFrames"][0], "ss_arg");
+                await CheckProps(ss_arg_props, ss_local_as_ss_arg, "ss_arg");
+
+                var res = await InvokeGetter(GetAndAssertObjectWithName(locals, "ss_arg"), "V");
+                await CheckValue(res.Value["result"], TNumber(0xDEADBEEF + (uint)dt.Month), "ss_arg#V");
+
+                {
+                    // Check ss_local.gs
+                    await CompareObjectPropertiesFor(ss_arg_props, "gs", ss_local_gs);
+                }
+
+                pause_location = await StepAndCheck(StepKind.Over, debugger_test_loc, 40, 8, "MethodWithStructArgs", times: 4,
+                    locals_fn: (l) => { /* non-null to make sure that locals get fetched */ });
+                locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value<string>());
+                {
+                    Assert.Equal(3, locals.Count());
+
+                    CheckString(locals, "label", "TestStructsAsMethodArgs#label");
+                    CheckValueType(locals, "ss_arg", "DebuggerTests.ValueTypesTest.SimpleStruct");
+                    CheckNumber(locals, "x", 3);
+                }
+
+                var ss_arg_updated = new
+                {
+                    V = TGetter("V"),
+                    str_member = TString("ValueTypesTest#MethodWithStructArgs#updated#ss_arg#str_member"),
+                    dt = TDateTime(dt),
+                    gs = TValueType("DebuggerTests.ValueTypesTest.GenericStruct<System.DateTime>"),
+                    Kind = TEnum("System.DateTimeKind", "Utc")
+                };
+
+                ss_arg_props = await GetObjectOnFrame(pause_location["callFrames"][0], "ss_arg");
+                await CheckProps(ss_arg_props, ss_arg_updated, "ss_arg");
+
+                res = await InvokeGetter(GetAndAssertObjectWithName(locals, "ss_arg"), "V");
+                await CheckValue(res.Value["result"], TNumber(0xDEADBEEF + (uint)dt.Month), "ss_arg#V");
+
+                {
+                    // Check ss_local.gs
+                    await CompareObjectPropertiesFor(ss_arg_props, "gs", new
+                    {
+                        StringField = TString("ValueTypesTest#MethodWithStructArgs#updated#gs#StringField#3"),
+                        List = TObject("System.Collections.Generic.List<System.DateTime>"),
+                        Options = TEnum("DebuggerTests.Options", "Option1")
+                    });
+                }
+
+                // Check locals on previous frame, same as earlier in this test
+                ss_arg_props = await GetObjectOnFrame(pause_location["callFrames"][1], "ss_local");
+                await CheckProps(ss_arg_props, ss_local_as_ss_arg, "ss_local");
+
+                {
+                    // Check ss_local.dt
+                    await CheckDateTime(ss_arg_props, "dt", dt);
+
+                    // Check ss_local.gs
+                    var gs_props = await GetObjectOnLocals(ss_arg_props, "gs");
+                    CheckString(gs_props, "StringField", "ss_local#SimpleStruct#string#0#SimpleStruct#gs#StringField");
+                    CheckObject(gs_props, "List", "System.Collections.Generic.List<System.DateTime>");
+                }
+
+                // ----------- Step back to the caller ---------
+
+                pause_location = await StepAndCheck(StepKind.Over, debugger_test_loc, 30, 12, "TestStructsAsMethodArgs",
+                    times: 2, locals_fn: (l) => { /* non-null to make sure that locals get fetched */ });
+                locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value<string>());
+                await CheckProps(locals, new
+                {
+                    ss_local = TValueType("DebuggerTests.ValueTypesTest.SimpleStruct"),
+                    ss_ret = TValueType("DebuggerTests.ValueTypesTest.SimpleStruct")
+                },
+                    "locals#0");
+
+                ss_arg_props = await GetObjectOnFrame(pause_location["callFrames"][0], "ss_local");
+                await CheckProps(ss_arg_props, ss_local_as_ss_arg, "ss_local");
+
+                {
+                    // Check ss_local.gs
+                    await CompareObjectPropertiesFor(ss_arg_props, "gs", ss_local_gs, label: "ss_local_gs");
+                }
+
+                // FIXME: check ss_local.gs.List's members
+            });
+        }
+
+        [Fact]
+        public async Task CheckUpdatedValueTypeFieldsOnResume()
+        {
+            var insp = new Inspector();
+            //Collect events
+            var scripts = SubscribeToScripts(insp);
+
+            await Ready();
+            await insp.Ready(async (cli, token) =>
+            {
+                ctx = new DebugTestContext(cli, insp, token, scripts);
+                var debugger_test_loc = "dotnet://debugger-test.dll/debugger-valuetypes-test.cs";
+
+                var lines = new[] { 205, 208 };
+                await SetBreakpoint(debugger_test_loc, lines[0], 12);
+                await SetBreakpoint(debugger_test_loc, lines[1], 12);
+
+                var pause_location = await EvaluateAndCheck(
+                    "window.setTimeout(function() { invoke_static_method ('[debugger-test] DebuggerTests.ValueTypesTest:MethodUpdatingValueTypeMembers'); }, 1);",
+                    debugger_test_loc, lines[0], 12, "MethodUpdatingValueTypeMembers");
+
+                await CheckLocals(pause_location, new DateTime(1, 2, 3, 4, 5, 6), new DateTime(4, 5, 6, 7, 8, 9));
+
+                // Resume
+                pause_location = await SendCommandAndCheck(JObject.FromObject(new { }), "Debugger.resume", debugger_test_loc, lines[1], 12, "MethodUpdatingValueTypeMembers");
+                await CheckLocals(pause_location, new DateTime(9, 8, 7, 6, 5, 4), new DateTime(5, 1, 3, 7, 9, 10));
+            });
+
+            async Task CheckLocals(JToken pause_location, DateTime obj_dt, DateTime vt_dt)
+            {
+                var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value<string>());
+                await CheckProps(locals, new
+                {
+                    obj = TObject("DebuggerTests.ClassForToStringTests"),
+                    vt = TObject("DebuggerTests.StructForToStringTests")
+                }, "locals");
+
+                var obj_props = await GetObjectOnLocals(locals, "obj");
+                {
+                    await CheckProps(obj_props, new
+                    {
+                        DT = TDateTime(obj_dt)
+                    }, "locals#obj.DT", num_fields: 5);
+                }
+
+                var vt_props = await GetObjectOnLocals(locals, "vt");
+                {
+                    await CheckProps(vt_props, new
+                    {
+                        DT = TDateTime(vt_dt)
+                    }, "locals#obj.DT", num_fields: 5);
+                }
+            }
+        }
+
+        [Fact]
+        public async Task CheckUpdatedValueTypeLocalsOnResumeAsync()
+        {
+            var insp = new Inspector();
+            //Collect events
+            var scripts = SubscribeToScripts(insp);
+
+            await Ready();
+            await insp.Ready(async (cli, token) =>
+            {
+                ctx = new DebugTestContext(cli, insp, token, scripts);
+                var debugger_test_loc = "dotnet://debugger-test.dll/debugger-valuetypes-test.cs";
+
+                var lines = new[] { 214, 216 };
+                await SetBreakpoint(debugger_test_loc, lines[0], 12);
+                await SetBreakpoint(debugger_test_loc, lines[1], 12);
+
+                var pause_location = await EvaluateAndCheck(
+                    "window.setTimeout(function() { invoke_static_method ('[debugger-test] DebuggerTests.ValueTypesTest:MethodUpdatingValueTypeLocalsAsync'); }, 1);",
+                    debugger_test_loc, lines[0], 12, "MoveNext");
+
+                var dt = new DateTime(1, 2, 3, 4, 5, 6);
+                var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value<string>());
+                await CheckDateTime(locals, "dt", dt);
+
+                // Resume
+                dt = new DateTime(9, 8, 7, 6, 5, 4);
+                pause_location = await SendCommandAndCheck(JObject.FromObject(new { }), "Debugger.resume", debugger_test_loc, lines[1], 12, "MoveNext");
+                locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value<string>());
+                await CheckDateTime(locals, "dt", dt);
+            });
+        }
+
+        [Fact]
+        public async Task CheckUpdatedVTArrayMembersOnResume()
+        {
+            var insp = new Inspector();
+            //Collect events
+            var scripts = SubscribeToScripts(insp);
+
+            await Ready();
+            await insp.Ready(async (cli, token) =>
+            {
+                ctx = new DebugTestContext(cli, insp, token, scripts);
+                var debugger_test_loc = "dotnet://debugger-test.dll/debugger-valuetypes-test.cs";
+
+                var lines = new[] { 225, 227 };
+                await SetBreakpoint(debugger_test_loc, lines[0], 12);
+                await SetBreakpoint(debugger_test_loc, lines[1], 12);
+
+                var dt = new DateTime(1, 2, 3, 4, 5, 6);
+                var pause_location = await EvaluateAndCheck(
+                    "window.setTimeout(function() { invoke_static_method ('[debugger-test] DebuggerTests.ValueTypesTest:MethodUpdatingVTArrayMembers'); }, 1);",
+                    debugger_test_loc, lines[0], 12, "MethodUpdatingVTArrayMembers");
+                await CheckArrayElements(pause_location, dt);
+
+                // Resume
+                dt = new DateTime(9, 8, 7, 6, 5, 4);
+                pause_location = await SendCommandAndCheck(JObject.FromObject(new { }), "Debugger.resume", debugger_test_loc, lines[1], 12, "MethodUpdatingVTArrayMembers");
+                await CheckArrayElements(pause_location, dt);
+            });
+
+            async Task CheckArrayElements(JToken pause_location, DateTime dt)
+            {
+                var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value<string>());
+                await CheckProps(locals, new
+                {
+                    ssta = TArray("DebuggerTests.StructForToStringTests[]", 1)
+                }, "locals");
+
+                var ssta = await GetObjectOnLocals(locals, "ssta");
+                var sst0 = await GetObjectOnLocals(ssta, "0");
+                await CheckProps(sst0, new
+                {
+                    DT = TDateTime(dt)
+                }, "dta [0]", num_fields: 5);
+            }
+        }
+
+        [Fact]
+        public async Task SteppingIntoMscorlib()
+        {
+            var insp = new Inspector();
+            //Collect events
+            var scripts = SubscribeToScripts(insp);
+
+            await Ready();
+            await insp.Ready(async (cli, token) =>
+            {
+                ctx = new DebugTestContext(cli, insp, token, scripts);
+
+                var bp = await SetBreakpoint("dotnet://debugger-test.dll/debugger-test.cs", 83, 8);
+                var pause_location = await EvaluateAndCheck(
+                    "window.setTimeout(function() { invoke_static_method ('[debugger-test] Math:OuterMethod'); }, 1);",
+                    "dotnet://debugger-test.dll/debugger-test.cs", 83, 8,
+                    "OuterMethod");
+
+                //make sure we're on the right bp
+                Assert.Equal(bp.Value["breakpointId"]?.ToString(), pause_location["hitBreakpoints"]?[0]?.Value<string>());
+
+                pause_location = await SendCommandAndCheck(null, $"Debugger.stepInto", null, -1, -1, null);
+                var top_frame = pause_location["callFrames"][0];
+
+                AssertEqual("WriteLine", top_frame["functionName"]?.Value<string>(), "Expected to be in WriteLine method");
+                var script_id = top_frame["functionLocation"]["scriptId"].Value<string>();
+                Assert.Matches ("^dotnet://(mscorlib|System\\.Console)\\.dll/Console.cs", scripts[script_id]);
+            });
+        }
+
+        [Fact]
+        public async Task CreateGoodBreakpointAndHitAndRemoveAndDontHit()
+        {
+            var insp = new Inspector();
+
+            //Collect events
+            var scripts = SubscribeToScripts(insp);
+
+            await Ready();
+            await insp.Ready(async (cli, token) =>
+            {
+                ctx = new DebugTestContext(cli, insp, token, scripts);
+
+                var bp = await SetBreakpoint("dotnet://debugger-test.dll/debugger-test.cs", 10, 8);
+                var bp2 = await SetBreakpoint("dotnet://debugger-test.dll/debugger-test.cs", 12, 8);
+                var pause_location = await EvaluateAndCheck(
+                    "window.setTimeout(function() { invoke_add(); invoke_add()}, 1);",
+                    "dotnet://debugger-test.dll/debugger-test.cs",  10, 8,
+                    "IntAdd");
+
+                Assert.Equal("other", pause_location["reason"]?.Value<string>());
+                Assert.Equal(bp.Value["breakpointId"]?.ToString(), pause_location["hitBreakpoints"]?[0]?.Value<string>());
+
+                await RemoveBreakpoint(bp.Value["breakpointId"]?.ToString());
+                await SendCommandAndCheck(JObject.FromObject(new { }), "Debugger.resume", "dotnet://debugger-test.dll/debugger-test.cs", 12, 8, "IntAdd");
+                await SendCommandAndCheck(JObject.FromObject(new { }), "Debugger.resume", "dotnet://debugger-test.dll/debugger-test.cs", 12, 8, "IntAdd");
+            });
+        }
+
+        [Fact]
+        public async Task CreateGoodBreakpointAndHitAndRemoveTwice()
+        {
+            var insp = new Inspector();
+
+            //Collect events
+            var scripts = SubscribeToScripts(insp);
+
+            await Ready();
+            await insp.Ready(async (cli, token) =>
+            {
+                ctx = new DebugTestContext(cli, insp, token, scripts);
+
+                var bp = await SetBreakpoint("dotnet://debugger-test.dll/debugger-test.cs", 10, 8);
+                var bp2 = await SetBreakpoint("dotnet://debugger-test.dll/debugger-test.cs", 12, 8);
+                var pause_location = await EvaluateAndCheck(
+                    "window.setTimeout(function() { invoke_add(); invoke_add()}, 1);",
+                    "dotnet://debugger-test.dll/debugger-test.cs",  10, 8,
+                    "IntAdd");
+
+                Assert.Equal("other", pause_location["reason"]?.Value<string>());
+                Assert.Equal(bp.Value["breakpointId"]?.ToString(), pause_location["hitBreakpoints"]?[0]?.Value<string>());
+
+                await RemoveBreakpoint(bp.Value["breakpointId"]?.ToString());
+                await RemoveBreakpoint(bp.Value["breakpointId"]?.ToString());
+            });
+        }
+
+        [Fact]
+        public async Task CreateGoodBreakpointAndHitAndRemoveAndDontHitAndCreateAgainAndHit()
+        {
+            var insp = new Inspector();
+
+            //Collect events
+            var scripts = SubscribeToScripts(insp);
+
+            await Ready();
+            await insp.Ready(async (cli, token) =>
+            {
+                ctx = new DebugTestContext(cli, insp, token, scripts);
+
+                var bp = await SetBreakpoint("dotnet://debugger-test.dll/debugger-test.cs", 10, 8);
+                var bp2 = await SetBreakpoint("dotnet://debugger-test.dll/debugger-test.cs", 12, 8);
+                var pause_location = await EvaluateAndCheck(
+                    "window.setTimeout(function() { invoke_add(); invoke_add(); invoke_add(); invoke_add()}, 1);",
+                    "dotnet://debugger-test.dll/debugger-test.cs",  10, 8,
+                    "IntAdd");
+
+                Assert.Equal("other", pause_location["reason"]?.Value<string>());
+                Assert.Equal(bp.Value["breakpointId"]?.ToString(), pause_location["hitBreakpoints"]?[0]?.Value<string>());
+
+                await RemoveBreakpoint(bp.Value["breakpointId"]?.ToString());
+                await SendCommandAndCheck(JObject.FromObject(new { }), "Debugger.resume", "dotnet://debugger-test.dll/debugger-test.cs", 12, 8, "IntAdd");
+                await SendCommandAndCheck(JObject.FromObject(new { }), "Debugger.resume", "dotnet://debugger-test.dll/debugger-test.cs", 12, 8, "IntAdd");
+                bp = await SetBreakpoint("dotnet://debugger-test.dll/debugger-test.cs", 10, 8);
+                await SendCommandAndCheck(JObject.FromObject(new { }), "Debugger.resume", "dotnet://debugger-test.dll/debugger-test.cs", 10, 8, "IntAdd");
+
+            });
+        }
+
+        // [Fact]
+        //https://github.com/dotnet/runtime/issues/42421
+        public async Task BreakAfterAwaitThenStepOverTillBackToCaller()
+        {
+            var insp = new Inspector();
+            //Collect events
+            var scripts = SubscribeToScripts(insp);
+
+            await Ready();
+            await insp.Ready(async (cli, token) =>
+            {
+                ctx = new DebugTestContext(cli, insp, token, scripts);
+
+                var bp = await SetBreakpointInMethod("debugger-test.dll", "DebuggerTests.AsyncStepClass", "TestAsyncStepOut2", 2);
+                await EvaluateAndCheck(
+                    "window.setTimeout(function() { invoke_static_method_async('[debugger-test] DebuggerTests.AsyncStepClass:TestAsyncStepOut'); }, 1);",
+                    "dotnet://debugger-test.dll/debugger-async-step.cs", 21, 12,
+                    "MoveNext");
+
+                await StepAndCheck(StepKind.Over, "dotnet://debugger-test.dll/debugger-async-step.cs", 23, 12, "MoveNext");
+
+                await StepAndCheck(StepKind.Over, "dotnet://debugger-test.dll/debugger-async-step.cs", 24, 8, "MoveNext");
+
+                await StepAndCheck(StepKind.Over, "dotnet://debugger-test.dll/debugger-async-step.cs", 15, 12, "MoveNext");
+            });
+        }
+
+        // [Fact]
+        //[ActiveIssue("https://github.com/dotnet/runtime/issues/42421")]
+        public async Task StepOutOfAsyncMethod()
+        {
+            var insp = new Inspector();
+            //Collect events
+            var scripts = SubscribeToScripts(insp);
+
+            await Ready();
+            await insp.Ready(async (cli, token) =>
+            {
+                ctx = new DebugTestContext(cli, insp, token, scripts);
+                string source_file = "dotnet://debugger-test.dll/debugger-async-step.cs";
+
+                await SetBreakpointInMethod("debugger-test.dll", "DebuggerTests.AsyncStepClass", "TestAsyncStepOut2", 2);
+                await EvaluateAndCheck(
+                    "window.setTimeout(function() { invoke_static_method_async('[debugger-test] DebuggerTests.AsyncStepClass:TestAsyncStepOut'); }, 1);",
+                    "dotnet://debugger-test.dll/debugger-async-step.cs", 21, 12,
+                    "MoveNext");
+
+                await StepAndCheck(StepKind.Out, source_file, 15, 4, "TestAsyncStepOut");
+            });
+        }
+
+        [Fact]
+        public async Task ResumeOutOfAsyncMethodToAsyncCallerWithBreakpoint()
+        {
+            var insp = new Inspector();
+            //Collect events
+            var scripts = SubscribeToScripts(insp);
+
+            await Ready();
+            await insp.Ready(async (cli, token) =>
+            {
+                ctx = new DebugTestContext(cli, insp, token, scripts);
+                string source_file = "dotnet://debugger-test.dll/debugger-async-step.cs";
+
+                await SetBreakpointInMethod("debugger-test.dll", "DebuggerTests.AsyncStepClass", "TestAsyncStepOut2", 2);
+                await EvaluateAndCheck(
+                    "window.setTimeout(function() { invoke_static_method_async('[debugger-test] DebuggerTests.AsyncStepClass:TestAsyncStepOut'); }, 1);",
+                    "dotnet://debugger-test.dll/debugger-async-step.cs", 21, 12,
+                    "MoveNext");
+
+                await SetBreakpointInMethod("debugger-test.dll", "DebuggerTests.AsyncStepClass", "TestAsyncStepOut", 2);
+                await SendCommandAndCheck(null, "Debugger.resume", source_file, 16, 8, "MoveNext");
+            });
+        }
+
+        [Fact]
+        public async Task StepOutOfNonAsyncMethod()
+        {
+            var insp = new Inspector();
+            //Collect events
+            var scripts = SubscribeToScripts(insp);
+
+            await Ready();
+            await insp.Ready(async (cli, token) =>
+            {
+                ctx = new DebugTestContext(cli, insp, token, scripts);
+                string source_file = "dotnet://debugger-test.dll/debugger-async-step.cs";
+
+                await SetBreakpointInMethod("debugger-test.dll", "DebuggerTests.AsyncStepClass", "OtherMethod0", 1);
+                await EvaluateAndCheck(
+                    "window.setTimeout(function() { invoke_static_method_async('[debugger-test] DebuggerTests.AsyncStepClass:SimpleMethod'); }, 1);",
+                    source_file, -1, -1,
+                    "OtherMethod0");
+
+                await StepAndCheck(StepKind.Out, source_file, 29, 12, "SimpleMethod");
+            });
+        }
+
+        // [Fact]
+        // [ActiveIssue("https://github.com/dotnet/runtime/issues/42424")]
+        public async Task BreakOnAwaitThenStepOverToNextAwaitCall()
+        {
+            var insp = new Inspector();
+            //Collect events
+            var scripts = SubscribeToScripts(insp);
+
+            await Ready();
+            await insp.Ready(async (cli, token) =>
+            {
+                ctx = new DebugTestContext(cli, insp, token, scripts);
+                string source_file = "dotnet://debugger-test.dll/debugger-async-step.cs";
+
+                await SetBreakpointInMethod("debugger-test.dll", "DebuggerTests.AsyncStepClass", "MethodWithTwoAwaitsAsync", 2);
+                await EvaluateAndCheck(
+                    "window.setTimeout(function() { invoke_static_method_async('[debugger-test] DebuggerTests.AsyncStepClass:StepOverTestAsync'); }, 1);",
+                    "dotnet://debugger-test.dll/debugger-async-step.cs", 53, 12,
+                    "MoveNext");
+
+                await StepAndCheck(StepKind.Over, source_file, 54, 12, "MoveNext");
+            });
+        }
+
+        // [Fact]
+        // [ActiveIssue("https://github.com/dotnet/runtime/issues/42424")]
+        public async Task BreakOnAwaitThenStepOverToNextLine()
+        {
+            var insp = new Inspector();
+            //Collect events
+            var scripts = SubscribeToScripts(insp);
+
+            await Ready();
+            await insp.Ready(async (cli, token) =>
+            {
+                ctx = new DebugTestContext(cli, insp, token, scripts);
+                string source_file = "dotnet://debugger-test.dll/debugger-async-step.cs";
+
+                await SetBreakpointInMethod("debugger-test.dll", "DebuggerTests.AsyncStepClass", "StepOverTestAsync", 1);
+                await EvaluateAndCheck(
+                    "window.setTimeout(function() { invoke_static_method_async('[debugger-test] DebuggerTests.AsyncStepClass:StepOverTestAsync'); }, 1);",
+                    "dotnet://debugger-test.dll/debugger-async-step.cs", 46, 12,
+                    "MoveNext");
+
+                // BUG: chrome: not able to show any bp line indicator
+                await StepAndCheck(StepKind.Over, source_file, 47, 12, "MoveNext");
+            });
+        }
+
+        [Fact]
+        public async Task BreakOnAwaitThenResumeToNextBreakpoint()
+        {
+            var insp = new Inspector();
+            //Collect events
+            var scripts = SubscribeToScripts(insp);
+
+            await Ready();
+            await insp.Ready(async (cli, token) =>
+            {
+                ctx = new DebugTestContext(cli, insp, token, scripts);
+                string source_file = "dotnet://debugger-test.dll/debugger-async-step.cs";
+
+                await SetBreakpointInMethod("debugger-test.dll", "DebuggerTests.AsyncStepClass", "StepOverTestAsync", 1);
+                await SetBreakpointInMethod("debugger-test.dll", "DebuggerTests.AsyncStepClass", "StepOverTestAsync", 3);
+
+                await EvaluateAndCheck(
+                    "window.setTimeout(function() { invoke_static_method_async('[debugger-test] DebuggerTests.AsyncStepClass:StepOverTestAsync'); }, 1);",
+                    "dotnet://debugger-test.dll/debugger-async-step.cs", 46, 12,
+                    "MoveNext");
+
+                await StepAndCheck(StepKind.Resume, source_file, 48, 8, "MoveNext");
+            });
+        }
+
+        [Fact]
+        public async Task BreakOnAwaitThenResumeToNextBreakpointAfterSecondAwaitInSameMethod()
+        {
+            var insp = new Inspector();
+            //Collect events
+            var scripts = SubscribeToScripts(insp);
+
+            await Ready();
+            await insp.Ready(async (cli, token) =>
+            {
+                ctx = new DebugTestContext(cli, insp, token, scripts);
+                string source_file = "dotnet://debugger-test.dll/debugger-async-step.cs";
+
+                await SetBreakpointInMethod("debugger-test.dll", "DebuggerTests.AsyncStepClass", "MethodWithTwoAwaitsAsync", 1);
+                await SetBreakpointInMethod("debugger-test.dll", "DebuggerTests.AsyncStepClass", "MethodWithTwoAwaitsAsync", 5);
+
+                await EvaluateAndCheck(
+                    "window.setTimeout(function() { invoke_static_method_async('[debugger-test] DebuggerTests.AsyncStepClass:StepOverTestAsync'); }, 1);",
+                    "dotnet://debugger-test.dll/debugger-async-step.cs", 52, 12,
+                    "MoveNext");
+
+                await StepAndCheck(StepKind.Resume, source_file, 56, 12, "MoveNext");
+            });
+        }
+    }
+}
index 4c1ff5d..581b7b5 100644 (file)
@@ -480,14 +480,15 @@ namespace DebuggerTests
         internal async Task<JObject> StepAndCheck(StepKind kind, string script_loc, int line, int column, string function_name,
             Func<JObject, Task> wait_for_event_fn = null, Action<JToken> locals_fn = null, int times = 1)
         {
+            string method = (kind == StepKind.Resume ? "Debugger.resume" : $"Debugger.step{kind}");
             for (int i = 0; i < times - 1; i++)
             {
-                await SendCommandAndCheck(null, $"Debugger.step{kind.ToString()}", null, -1, -1, null);
+                await SendCommandAndCheck(null, method, null, -1, -1, null);
             }
 
             // Check for method/line etc only at the last step
             return await SendCommandAndCheck(
-                null, $"Debugger.step{kind.ToString()}", script_loc, line, column, function_name,
+                null, method, script_loc, line, column, function_name,
                 wait_for_event_fn: wait_for_event_fn,
                 locals_fn: locals_fn);
         }
@@ -510,12 +511,15 @@ namespace DebuggerTests
             }
 
             var wait_res = await ctx.insp.WaitFor(waitForEvent);
-
+            JToken top_frame = wait_res["callFrames"]?[0];
             if (function_name != null)
-                Assert.Equal(function_name, wait_res["callFrames"]?[0]?["functionName"]?.Value<string>());
+            {
+                AssertEqual(function_name, wait_res["callFrames"]?[0]?["functionName"]?.Value<string>(), top_frame?.ToString());
+            }
 
-            if (script_loc != null)
-                CheckLocation(script_loc, line, column, ctx.scripts, wait_res["callFrames"][0]["location"]);
+            Console.WriteLine (top_frame);
+            if (script_loc != null && line >= 0)
+                CheckLocation(script_loc, line, column, ctx.scripts, top_frame["location"]);
 
             if (wait_for_event_fn != null)
                 await wait_for_event_fn(wait_res);
@@ -1094,6 +1098,7 @@ namespace DebuggerTests
     {
         Into,
         Over,
-        Out
+        Out,
+        Resume
     }
 }
index d33fe76..c53a60b 100644 (file)
@@ -496,419 +496,6 @@ namespace DebuggerTests
             });
         }
 
-        [Fact]
-        public async Task TrivalStepping()
-        {
-            var insp = new Inspector();
-            //Collect events
-            var scripts = SubscribeToScripts(insp);
-
-            await Ready();
-            await insp.Ready(async (cli, token) =>
-            {
-                ctx = new DebugTestContext(cli, insp, token, scripts);
-
-                var bp = await SetBreakpoint("dotnet://debugger-test.dll/debugger-test.cs", 10, 8);
-
-                await EvaluateAndCheck(
-                    "window.setTimeout(function() { invoke_add(); }, 1);",
-                    "dotnet://debugger-test.dll/debugger-test.cs", 10, 8,
-                    "IntAdd",
-                    wait_for_event_fn: (pause_location) =>
-                    {
-                        //make sure we're on the right bp
-                        Assert.Equal(bp.Value["breakpointId"]?.ToString(), pause_location["hitBreakpoints"]?[0]?.Value<string>());
-
-                        var top_frame = pause_location["callFrames"][0];
-                        CheckLocation("dotnet://debugger-test.dll/debugger-test.cs", 8, 4, scripts, top_frame["functionLocation"]);
-                        return Task.CompletedTask;
-                    }
-                );
-
-                await StepAndCheck(StepKind.Over, "dotnet://debugger-test.dll/debugger-test.cs", 11, 8, "IntAdd",
-                    wait_for_event_fn: (pause_location) =>
-                    {
-                        var top_frame = pause_location["callFrames"][0];
-                        CheckLocation("dotnet://debugger-test.dll/debugger-test.cs", 8, 4, scripts, top_frame["functionLocation"]);
-                        return Task.CompletedTask;
-                    }
-                );
-            });
-        }
-
-        [Fact]
-        public async Task InspectLocalsDuringStepping()
-        {
-            var insp = new Inspector();
-            //Collect events
-            var scripts = SubscribeToScripts(insp);
-
-            await Ready();
-            await insp.Ready(async (cli, token) =>
-            {
-                ctx = new DebugTestContext(cli, insp, token, scripts);
-
-                var debugger_test_loc = "dotnet://debugger-test.dll/debugger-test.cs";
-                await SetBreakpoint(debugger_test_loc, 10, 8);
-
-                await EvaluateAndCheck(
-                    "window.setTimeout(function() { invoke_add(); }, 1);",
-                    debugger_test_loc, 10, 8, "IntAdd",
-                    locals_fn: (locals) =>
-                    {
-                        CheckNumber(locals, "a", 10);
-                        CheckNumber(locals, "b", 20);
-                        CheckNumber(locals, "c", 30);
-                        CheckNumber(locals, "d", 0);
-                        CheckNumber(locals, "e", 0);
-                    }
-                );
-
-                await StepAndCheck(StepKind.Over, debugger_test_loc, 11, 8, "IntAdd",
-                    locals_fn: (locals) =>
-                    {
-                        CheckNumber(locals, "a", 10);
-                        CheckNumber(locals, "b", 20);
-                        CheckNumber(locals, "c", 30);
-                        CheckNumber(locals, "d", 50);
-                        CheckNumber(locals, "e", 0);
-                    }
-                );
-
-                //step and get locals
-                await StepAndCheck(StepKind.Over, debugger_test_loc, 12, 8, "IntAdd",
-                    locals_fn: (locals) =>
-                    {
-                        CheckNumber(locals, "a", 10);
-                        CheckNumber(locals, "b", 20);
-                        CheckNumber(locals, "c", 30);
-                        CheckNumber(locals, "d", 50);
-                        CheckNumber(locals, "e", 60);
-                    }
-                );
-            });
-        }
-
-        [Theory]
-        [InlineData(false)]
-        [InlineData(true)]
-        public async Task InspectLocalsInPreviousFramesDuringSteppingIn2(bool use_cfo)
-        {
-            var insp = new Inspector();
-            //Collect events
-            var scripts = SubscribeToScripts(insp);
-
-            await Ready();
-            await insp.Ready(async (cli, token) =>
-            {
-                ctx = new DebugTestContext(cli, insp, token, scripts);
-                ctx.UseCallFunctionOnBeforeGetProperties = use_cfo;
-
-                var dep_cs_loc = "dotnet://debugger-test.dll/dependency.cs";
-                await SetBreakpoint(dep_cs_loc, 33, 8);
-
-                var debugger_test_loc = "dotnet://debugger-test.dll/debugger-test.cs";
-
-                // Will stop in Complex.DoEvenMoreStuff
-                var pause_location = await EvaluateAndCheck(
-                    "window.setTimeout(function() { invoke_use_complex (); }, 1);",
-                    dep_cs_loc, 33, 8, "DoEvenMoreStuff",
-                    locals_fn: (locals) =>
-                    {
-                        Assert.Single(locals);
-                        CheckObject(locals, "this", "Simple.Complex");
-                    }
-                );
-
-                var props = await GetObjectOnFrame(pause_location["callFrames"][0], "this");
-                Assert.Equal(3, props.Count());
-                CheckNumber(props, "A", 10);
-                CheckString(props, "B", "xx");
-                CheckString(props, "c", "20_xx");
-
-                // Check UseComplex frame
-                var locals_m1 = await GetLocalsForFrame(pause_location["callFrames"][3], debugger_test_loc, 23, 8, "UseComplex");
-                Assert.Equal(7, locals_m1.Count());
-
-                CheckNumber(locals_m1, "a", 10);
-                CheckNumber(locals_m1, "b", 20);
-                CheckObject(locals_m1, "complex", "Simple.Complex");
-                CheckNumber(locals_m1, "c", 30);
-                CheckNumber(locals_m1, "d", 50);
-                CheckNumber(locals_m1, "e", 60);
-                CheckNumber(locals_m1, "f", 0);
-
-                props = await GetObjectOnFrame(pause_location["callFrames"][3], "complex");
-                Assert.Equal(3, props.Count());
-                CheckNumber(props, "A", 10);
-                CheckString(props, "B", "xx");
-                CheckString(props, "c", "20_xx");
-
-                pause_location = await StepAndCheck(StepKind.Over, dep_cs_loc, 23, 8, "DoStuff", times: 2);
-                // Check UseComplex frame again
-                locals_m1 = await GetLocalsForFrame(pause_location["callFrames"][1], debugger_test_loc, 23, 8, "UseComplex");
-                Assert.Equal(7, locals_m1.Count());
-
-                CheckNumber(locals_m1, "a", 10);
-                CheckNumber(locals_m1, "b", 20);
-                CheckObject(locals_m1, "complex", "Simple.Complex");
-                CheckNumber(locals_m1, "c", 30);
-                CheckNumber(locals_m1, "d", 50);
-                CheckNumber(locals_m1, "e", 60);
-                CheckNumber(locals_m1, "f", 0);
-
-                props = await GetObjectOnFrame(pause_location["callFrames"][1], "complex");
-                Assert.Equal(3, props.Count());
-                CheckNumber(props, "A", 10);
-                CheckString(props, "B", "xx");
-                CheckString(props, "c", "20_xx");
-            });
-        }
-
-        [Theory]
-        [InlineData(false)]
-        [InlineData(true)]
-        public async Task InspectLocalsInPreviousFramesDuringSteppingIn(bool use_cfo)
-        {
-            var insp = new Inspector();
-            //Collect events
-            var scripts = SubscribeToScripts(insp);
-
-            await Ready();
-            await insp.Ready(async (cli, token) =>
-            {
-                ctx = new DebugTestContext(cli, insp, token, scripts);
-                ctx.UseCallFunctionOnBeforeGetProperties = use_cfo;
-
-                var debugger_test_loc = "dotnet://debugger-test.dll/debugger-test.cs";
-                await SetBreakpoint(debugger_test_loc, 111, 12);
-
-                // Will stop in InnerMethod
-                var wait_res = await EvaluateAndCheck(
-                    "window.setTimeout(function() { invoke_outer_method(); }, 1);",
-                    debugger_test_loc, 111, 12, "InnerMethod",
-                    locals_fn: (locals) =>
-                    {
-                        Assert.Equal(4, locals.Count());
-                        CheckNumber(locals, "i", 5);
-                        CheckNumber(locals, "j", 24);
-                        CheckString(locals, "foo_str", "foo");
-                        CheckObject(locals, "this", "Math.NestedInMath");
-                    }
-                );
-
-                var this_props = await GetObjectOnFrame(wait_res["callFrames"][0], "this");
-                Assert.Equal(2, this_props.Count());
-                CheckObject(this_props, "m", "Math");
-                CheckValueType(this_props, "SimpleStructProperty", "Math.SimpleStruct");
-
-                var ss_props = await GetObjectOnLocals(this_props, "SimpleStructProperty");
-                var dt = new DateTime(2020, 1, 2, 3, 4, 5);
-                await CheckProps(ss_props, new
-                {
-                    dt = TDateTime(dt),
-                    gs = TValueType("Math.GenericStruct<System.DateTime>")
-                }, "ss_props");
-
-                // Check OuterMethod frame
-                var locals_m1 = await GetLocalsForFrame(wait_res["callFrames"][1], debugger_test_loc, 87, 8, "OuterMethod");
-                Assert.Equal(5, locals_m1.Count());
-                // FIXME: Failing test CheckNumber (locals_m1, "i", 5);
-                // FIXME: Failing test CheckString (locals_m1, "text", "Hello");
-                CheckNumber(locals_m1, "new_i", 0);
-                CheckNumber(locals_m1, "k", 0);
-                CheckObject(locals_m1, "nim", "Math.NestedInMath");
-
-                // step back into OuterMethod
-                await StepAndCheck(StepKind.Over, debugger_test_loc, 91, 8, "OuterMethod", times: 9,
-                    locals_fn: (locals) =>
-                    {
-                        Assert.Equal(5, locals.Count());
-
-                        // FIXME: Failing test CheckNumber (locals_m1, "i", 5);
-                        CheckString(locals, "text", "Hello");
-                        // FIXME: Failing test CheckNumber (locals, "new_i", 24);
-                        CheckNumber(locals, "k", 19);
-                        CheckObject(locals, "nim", "Math.NestedInMath");
-                    }
-                );
-
-                //await StepAndCheck (StepKind.Over, "dotnet://debugger-test.dll/debugger-test.cs", 81, 2, "OuterMethod", times: 2);
-
-                // step into InnerMethod2
-                await StepAndCheck(StepKind.Into, "dotnet://debugger-test.dll/debugger-test.cs", 96, 4, "InnerMethod2",
-                    locals_fn: (locals) =>
-                    {
-                        Assert.Equal(3, locals.Count());
-
-                        CheckString(locals, "s", "test string");
-                        //out var: CheckNumber (locals, "k", 0);
-                        CheckNumber(locals, "i", 24);
-                    }
-                );
-
-                await StepAndCheck(StepKind.Over, "dotnet://debugger-test.dll/debugger-test.cs", 100, 4, "InnerMethod2", times: 4,
-                    locals_fn: (locals) =>
-                    {
-                        Assert.Equal(3, locals.Count());
-
-                        CheckString(locals, "s", "test string");
-                        // FIXME: Failing test CheckNumber (locals, "k", 34);
-                        CheckNumber(locals, "i", 24);
-                    }
-                );
-
-                await StepAndCheck(StepKind.Over, "dotnet://debugger-test.dll/debugger-test.cs", 92, 8, "OuterMethod", times: 2,
-                    locals_fn: (locals) =>
-                    {
-                        Assert.Equal(5, locals.Count());
-
-                        CheckString(locals, "text", "Hello");
-                        // FIXME: failing test CheckNumber (locals, "i", 5);
-                        CheckNumber(locals, "new_i", 22);
-                        CheckNumber(locals, "k", 34);
-                        CheckObject(locals, "nim", "Math.NestedInMath");
-                    }
-                );
-            });
-        }
-
-        [Fact]
-        public async Task InspectLocalsDuringSteppingIn()
-        {
-            var insp = new Inspector();
-            //Collect events
-            var scripts = SubscribeToScripts(insp);
-
-            await Ready();
-            await insp.Ready(async (cli, token) =>
-            {
-                ctx = new DebugTestContext(cli, insp, token, scripts);
-
-                await SetBreakpoint("dotnet://debugger-test.dll/debugger-test.cs", 86, 8);
-
-                await EvaluateAndCheck("window.setTimeout(function() { invoke_outer_method(); }, 1);",
-                    "dotnet://debugger-test.dll/debugger-test.cs", 86, 8, "OuterMethod",
-                    locals_fn: (locals) =>
-                    {
-                        Assert.Equal(5, locals.Count());
-
-                        CheckObject(locals, "nim", "Math.NestedInMath");
-                        CheckNumber(locals, "i", 5);
-                        CheckNumber(locals, "k", 0);
-                        CheckNumber(locals, "new_i", 0);
-                        CheckString(locals, "text", null);
-                    }
-                );
-
-                await StepAndCheck(StepKind.Over, "dotnet://debugger-test.dll/debugger-test.cs", 87, 8, "OuterMethod",
-                    locals_fn: (locals) =>
-                    {
-                        Assert.Equal(5, locals.Count());
-
-                        CheckObject(locals, "nim", "Math.NestedInMath");
-                        // FIXME: Failing test CheckNumber (locals, "i", 5);
-                        CheckNumber(locals, "k", 0);
-                        CheckNumber(locals, "new_i", 0);
-                        CheckString(locals, "text", "Hello");
-                    }
-                );
-
-                // Step into InnerMethod
-                await StepAndCheck(StepKind.Into, "dotnet://debugger-test.dll/debugger-test.cs", 105, 8, "InnerMethod");
-                await StepAndCheck(StepKind.Over, "dotnet://debugger-test.dll/debugger-test.cs", 109, 12, "InnerMethod", times: 5,
-                    locals_fn: (locals) =>
-                    {
-                        Assert.Equal(4, locals.Count());
-
-                        CheckNumber(locals, "i", 5);
-                        CheckNumber(locals, "j", 15);
-                        CheckString(locals, "foo_str", "foo");
-                        CheckObject(locals, "this", "Math.NestedInMath");
-                    }
-                );
-
-                // Step back to OuterMethod
-                await StepAndCheck(StepKind.Over, "dotnet://debugger-test.dll/debugger-test.cs", 88, 8, "OuterMethod", times: 6,
-                    locals_fn: (locals) =>
-                    {
-                        Assert.Equal(5, locals.Count());
-
-                        CheckObject(locals, "nim", "Math.NestedInMath");
-                        // FIXME: Failing test CheckNumber (locals, "i", 5);
-                        CheckNumber(locals, "k", 0);
-                        CheckNumber(locals, "new_i", 24);
-                        CheckString(locals, "text", "Hello");
-                    }
-                );
-            });
-        }
-
-        [Theory]
-        [InlineData(false)]
-        [InlineData(true)]
-        public async Task InspectLocalsInAsyncMethods(bool use_cfo)
-        {
-            var insp = new Inspector();
-            //Collect events
-            var scripts = SubscribeToScripts(insp);
-
-            await Ready();
-            await insp.Ready(async (cli, token) =>
-            {
-                ctx = new DebugTestContext(cli, insp, token, scripts);
-                ctx.UseCallFunctionOnBeforeGetProperties = use_cfo;
-                var debugger_test_loc = "dotnet://debugger-test.dll/debugger-test.cs";
-
-                await SetBreakpoint(debugger_test_loc, 120, 12);
-                await SetBreakpoint(debugger_test_loc, 135, 12);
-
-                // Will stop in Asyncmethod0
-                var wait_res = await EvaluateAndCheck(
-                    "window.setTimeout(function() { invoke_async_method_with_await(); }, 1);",
-                    debugger_test_loc, 120, 12, "MoveNext", //FIXME:
-                    locals_fn: (locals) =>
-                    {
-                        Assert.Equal(4, locals.Count());
-                        CheckString(locals, "s", "string from js");
-                        CheckNumber(locals, "i", 42);
-                        CheckString(locals, "local0", "value0");
-                        CheckObject(locals, "this", "Math.NestedInMath");
-                    }
-                );
-                Console.WriteLine(wait_res);
-
-#if false // Disabled for now, as we don't have proper async traces
-                var locals = await GetProperties(wait_res["callFrames"][2]["callFrameId"].Value<string>());
-                Assert.Equal(4, locals.Count());
-                CheckString(locals, "ls", "string from jstest");
-                CheckNumber(locals, "li", 52);
-#endif
-
-                // TODO: previous frames have async machinery details, so no point checking that right now
-
-                var pause_loc = await SendCommandAndCheck(null, "Debugger.resume", debugger_test_loc, 135, 12, /*FIXME: "AsyncMethodNoReturn"*/ "MoveNext",
-                    locals_fn: (locals) =>
-                    {
-                        Assert.Equal(4, locals.Count());
-                        CheckString(locals, "str", "AsyncMethodNoReturn's local");
-                        CheckObject(locals, "this", "Math.NestedInMath");
-                        //FIXME: check fields
-                        CheckValueType(locals, "ss", "Math.SimpleStruct");
-                        CheckArray(locals, "ss_arr", "Math.SimpleStruct[]", 0);
-                        // TODO: struct fields
-                    }
-                );
-
-                var this_props = await GetObjectOnFrame(pause_loc["callFrames"][0], "this");
-                Assert.Equal(2, this_props.Count());
-                CheckObject(this_props, "m", "Math");
-                CheckValueType(this_props, "SimpleStructProperty", "Math.SimpleStruct");
-
-                // TODO: Check `this` properties
-            });
-        }
-
         [Theory]
         [InlineData(false)]
         [InlineData(true)]
@@ -1112,272 +699,6 @@ namespace DebuggerTests
                 }, "locals");
             });
 
-
-        [Theory]
-        [InlineData(false)]
-        [InlineData(true)]
-        public async Task InspectValueTypeMethodArgs(bool use_cfo)
-        {
-            var insp = new Inspector();
-            //Collect events
-            var scripts = SubscribeToScripts(insp);
-
-            await Ready();
-            await insp.Ready(async (cli, token) =>
-            {
-                ctx = new DebugTestContext(cli, insp, token, scripts);
-                ctx.UseCallFunctionOnBeforeGetProperties = use_cfo;
-                var debugger_test_loc = "dotnet://debugger-test.dll/debugger-valuetypes-test.cs";
-
-                await SetBreakpoint(debugger_test_loc, 36, 12);
-
-                var pause_location = await EvaluateAndCheck(
-                    "window.setTimeout(function() { invoke_static_method ('[debugger-test] DebuggerTests.ValueTypesTest:TestStructsAsMethodArgs'); }, 1);",
-                    debugger_test_loc, 36, 12, "MethodWithStructArgs");
-                var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value<string>());
-                {
-                    Assert.Equal(3, locals.Count());
-                    CheckString(locals, "label", "TestStructsAsMethodArgs#label");
-                    CheckValueType(locals, "ss_arg", "DebuggerTests.ValueTypesTest.SimpleStruct");
-                    CheckNumber(locals, "x", 3);
-                }
-
-                var dt = new DateTime(2025, 6, 7, 8, 10, 11);
-                var ss_local_as_ss_arg = new
-                {
-                    V = TGetter("V"),
-                    str_member = TString("ss_local#SimpleStruct#string#0#SimpleStruct#str_member"),
-                    dt = TDateTime(dt),
-                    gs = TValueType("DebuggerTests.ValueTypesTest.GenericStruct<System.DateTime>"),
-                    Kind = TEnum("System.DateTimeKind", "Local")
-                };
-                var ss_local_gs = new
-                {
-                    StringField = TString("ss_local#SimpleStruct#string#0#SimpleStruct#gs#StringField"),
-                    List = TObject("System.Collections.Generic.List<System.DateTime>"),
-                    Options = TEnum("DebuggerTests.Options", "Option1")
-                };
-
-                // Check ss_arg's properties
-                var ss_arg_props = await GetObjectOnFrame(pause_location["callFrames"][0], "ss_arg");
-                await CheckProps(ss_arg_props, ss_local_as_ss_arg, "ss_arg");
-
-                var res = await InvokeGetter(GetAndAssertObjectWithName(locals, "ss_arg"), "V");
-                await CheckValue(res.Value["result"], TNumber(0xDEADBEEF + (uint)dt.Month), "ss_arg#V");
-
-                {
-                    // Check ss_local.gs
-                    await CompareObjectPropertiesFor(ss_arg_props, "gs", ss_local_gs);
-                }
-
-                pause_location = await StepAndCheck(StepKind.Over, debugger_test_loc, 40, 8, "MethodWithStructArgs", times: 4,
-                    locals_fn: (l) => { /* non-null to make sure that locals get fetched */ });
-                locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value<string>());
-                {
-                    Assert.Equal(3, locals.Count());
-
-                    CheckString(locals, "label", "TestStructsAsMethodArgs#label");
-                    CheckValueType(locals, "ss_arg", "DebuggerTests.ValueTypesTest.SimpleStruct");
-                    CheckNumber(locals, "x", 3);
-                }
-
-                var ss_arg_updated = new
-                {
-                    V = TGetter("V"),
-                    str_member = TString("ValueTypesTest#MethodWithStructArgs#updated#ss_arg#str_member"),
-                    dt = TDateTime(dt),
-                    gs = TValueType("DebuggerTests.ValueTypesTest.GenericStruct<System.DateTime>"),
-                    Kind = TEnum("System.DateTimeKind", "Utc")
-                };
-
-                ss_arg_props = await GetObjectOnFrame(pause_location["callFrames"][0], "ss_arg");
-                await CheckProps(ss_arg_props, ss_arg_updated, "ss_arg");
-
-                res = await InvokeGetter(GetAndAssertObjectWithName(locals, "ss_arg"), "V");
-                await CheckValue(res.Value["result"], TNumber(0xDEADBEEF + (uint)dt.Month), "ss_arg#V");
-
-                {
-                    // Check ss_local.gs
-                    await CompareObjectPropertiesFor(ss_arg_props, "gs", new
-                    {
-                        StringField = TString("ValueTypesTest#MethodWithStructArgs#updated#gs#StringField#3"),
-                        List = TObject("System.Collections.Generic.List<System.DateTime>"),
-                        Options = TEnum("DebuggerTests.Options", "Option1")
-                    });
-                }
-
-                // Check locals on previous frame, same as earlier in this test
-                ss_arg_props = await GetObjectOnFrame(pause_location["callFrames"][1], "ss_local");
-                await CheckProps(ss_arg_props, ss_local_as_ss_arg, "ss_local");
-
-                {
-                    // Check ss_local.dt
-                    await CheckDateTime(ss_arg_props, "dt", dt);
-
-                    // Check ss_local.gs
-                    var gs_props = await GetObjectOnLocals(ss_arg_props, "gs");
-                    CheckString(gs_props, "StringField", "ss_local#SimpleStruct#string#0#SimpleStruct#gs#StringField");
-                    CheckObject(gs_props, "List", "System.Collections.Generic.List<System.DateTime>");
-                }
-
-                // ----------- Step back to the caller ---------
-
-                pause_location = await StepAndCheck(StepKind.Over, debugger_test_loc, 30, 12, "TestStructsAsMethodArgs",
-                    times: 2, locals_fn: (l) => { /* non-null to make sure that locals get fetched */ });
-                locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value<string>());
-                await CheckProps(locals, new
-                {
-                    ss_local = TValueType("DebuggerTests.ValueTypesTest.SimpleStruct"),
-                    ss_ret = TValueType("DebuggerTests.ValueTypesTest.SimpleStruct")
-                },
-                    "locals#0");
-
-                ss_arg_props = await GetObjectOnFrame(pause_location["callFrames"][0], "ss_local");
-                await CheckProps(ss_arg_props, ss_local_as_ss_arg, "ss_local");
-
-                {
-                    // Check ss_local.gs
-                    await CompareObjectPropertiesFor(ss_arg_props, "gs", ss_local_gs, label: "ss_local_gs");
-                }
-
-                // FIXME: check ss_local.gs.List's members
-            });
-        }
-
-        [Fact]
-        public async Task CheckUpdatedValueTypeFieldsOnResume()
-        {
-            var insp = new Inspector();
-            //Collect events
-            var scripts = SubscribeToScripts(insp);
-
-            await Ready();
-            await insp.Ready(async (cli, token) =>
-            {
-                ctx = new DebugTestContext(cli, insp, token, scripts);
-                var debugger_test_loc = "dotnet://debugger-test.dll/debugger-valuetypes-test.cs";
-
-                var lines = new[] { 205, 208 };
-                await SetBreakpoint(debugger_test_loc, lines[0], 12);
-                await SetBreakpoint(debugger_test_loc, lines[1], 12);
-
-                var pause_location = await EvaluateAndCheck(
-                    "window.setTimeout(function() { invoke_static_method ('[debugger-test] DebuggerTests.ValueTypesTest:MethodUpdatingValueTypeMembers'); }, 1);",
-                    debugger_test_loc, lines[0], 12, "MethodUpdatingValueTypeMembers");
-
-                await CheckLocals(pause_location, new DateTime(1, 2, 3, 4, 5, 6), new DateTime(4, 5, 6, 7, 8, 9));
-
-                // Resume
-                pause_location = await SendCommandAndCheck(JObject.FromObject(new { }), "Debugger.resume", debugger_test_loc, lines[1], 12, "MethodUpdatingValueTypeMembers");
-                await CheckLocals(pause_location, new DateTime(9, 8, 7, 6, 5, 4), new DateTime(5, 1, 3, 7, 9, 10));
-            });
-
-            async Task CheckLocals(JToken pause_location, DateTime obj_dt, DateTime vt_dt)
-            {
-                var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value<string>());
-                await CheckProps(locals, new
-                {
-                    obj = TObject("DebuggerTests.ClassForToStringTests"),
-                    vt = TObject("DebuggerTests.StructForToStringTests")
-                }, "locals");
-
-                var obj_props = await GetObjectOnLocals(locals, "obj");
-                {
-                    await CheckProps(obj_props, new
-                    {
-                        DT = TDateTime(obj_dt)
-                    }, "locals#obj.DT", num_fields: 5);
-                }
-
-                var vt_props = await GetObjectOnLocals(locals, "vt");
-                {
-                    await CheckProps(vt_props, new
-                    {
-                        DT = TDateTime(vt_dt)
-                    }, "locals#obj.DT", num_fields: 5);
-                }
-            }
-        }
-
-        [Fact]
-        public async Task CheckUpdatedValueTypeLocalsOnResumeAsync()
-        {
-            var insp = new Inspector();
-            //Collect events
-            var scripts = SubscribeToScripts(insp);
-
-            await Ready();
-            await insp.Ready(async (cli, token) =>
-            {
-                ctx = new DebugTestContext(cli, insp, token, scripts);
-                var debugger_test_loc = "dotnet://debugger-test.dll/debugger-valuetypes-test.cs";
-
-                var lines = new[] { 214, 216 };
-                await SetBreakpoint(debugger_test_loc, lines[0], 12);
-                await SetBreakpoint(debugger_test_loc, lines[1], 12);
-
-                var pause_location = await EvaluateAndCheck(
-                    "window.setTimeout(function() { invoke_static_method ('[debugger-test] DebuggerTests.ValueTypesTest:MethodUpdatingValueTypeLocalsAsync'); }, 1);",
-                    debugger_test_loc, lines[0], 12, "MoveNext");
-
-                var dt = new DateTime(1, 2, 3, 4, 5, 6);
-                var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value<string>());
-                await CheckDateTime(locals, "dt", dt);
-
-                // Resume
-                dt = new DateTime(9, 8, 7, 6, 5, 4);
-                pause_location = await SendCommandAndCheck(JObject.FromObject(new { }), "Debugger.resume", debugger_test_loc, lines[1], 12, "MoveNext");
-                locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value<string>());
-                await CheckDateTime(locals, "dt", dt);
-            });
-        }
-
-        [Fact]
-        public async Task CheckUpdatedVTArrayMembersOnResume()
-        {
-            var insp = new Inspector();
-            //Collect events
-            var scripts = SubscribeToScripts(insp);
-
-            await Ready();
-            await insp.Ready(async (cli, token) =>
-            {
-                ctx = new DebugTestContext(cli, insp, token, scripts);
-                var debugger_test_loc = "dotnet://debugger-test.dll/debugger-valuetypes-test.cs";
-
-                var lines = new[] { 225, 227 };
-                await SetBreakpoint(debugger_test_loc, lines[0], 12);
-                await SetBreakpoint(debugger_test_loc, lines[1], 12);
-
-                var dt = new DateTime(1, 2, 3, 4, 5, 6);
-                var pause_location = await EvaluateAndCheck(
-                    "window.setTimeout(function() { invoke_static_method ('[debugger-test] DebuggerTests.ValueTypesTest:MethodUpdatingVTArrayMembers'); }, 1);",
-                    debugger_test_loc, lines[0], 12, "MethodUpdatingVTArrayMembers");
-                await CheckArrayElements(pause_location, dt);
-
-                // Resume
-                dt = new DateTime(9, 8, 7, 6, 5, 4);
-                pause_location = await SendCommandAndCheck(JObject.FromObject(new { }), "Debugger.resume", debugger_test_loc, lines[1], 12, "MethodUpdatingVTArrayMembers");
-                await CheckArrayElements(pause_location, dt);
-            });
-
-            async Task CheckArrayElements(JToken pause_location, DateTime dt)
-            {
-                var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value<string>());
-                await CheckProps(locals, new
-                {
-                    ssta = TArray("DebuggerTests.StructForToStringTests[]", 1)
-                }, "locals");
-
-                var ssta = await GetObjectOnLocals(locals, "ssta");
-                var sst0 = await GetObjectOnLocals(ssta, "0");
-                await CheckProps(sst0, new
-                {
-                    DT = TDateTime(dt)
-                }, "dta [0]", num_fields: 5);
-            }
-        }
-
         [Theory]
         [InlineData(false)]
         [InlineData(true)]
@@ -1607,36 +928,6 @@ namespace DebuggerTests
            });
 
         [Fact]
-        public async Task SteppingIntoMscorlib()
-        {
-            var insp = new Inspector();
-            //Collect events
-            var scripts = SubscribeToScripts(insp);
-
-            await Ready();
-            await insp.Ready(async (cli, token) =>
-            {
-                ctx = new DebugTestContext(cli, insp, token, scripts);
-
-                var bp = await SetBreakpoint("dotnet://debugger-test.dll/debugger-test.cs", 83, 8);
-                var pause_location = await EvaluateAndCheck(
-                    "window.setTimeout(function() { invoke_static_method ('[debugger-test] Math:OuterMethod'); }, 1);",
-                    "dotnet://debugger-test.dll/debugger-test.cs", 83, 8,
-                    "OuterMethod");
-
-                //make sure we're on the right bp
-                Assert.Equal(bp.Value["breakpointId"]?.ToString(), pause_location["hitBreakpoints"]?[0]?.Value<string>());
-
-                pause_location = await SendCommandAndCheck(null, $"Debugger.stepInto", null, -1, -1, null);
-                var top_frame = pause_location["callFrames"][0];
-
-                AssertEqual("WriteLine", top_frame["functionName"]?.Value<string>(), "Expected to be in WriteLine method");
-                var script_id = top_frame["functionLocation"]["scriptId"].Value<string>();
-                Assert.Matches ("^dotnet://(mscorlib|System\\.Console)\\.dll/Console.cs", scripts[script_id]);
-            });
-        }
-
-        [Fact]
         public async Task InvalidValueTypeData()
         {
             await CheckInspectLocalsAtBreakpointSite(
@@ -1674,95 +965,6 @@ namespace DebuggerTests
         }
 
         [Fact]
-        public async Task CreateGoodBreakpointAndHitAndRemoveAndDontHit()
-        {
-            var insp = new Inspector();
-
-            //Collect events
-            var scripts = SubscribeToScripts(insp);
-
-            await Ready();
-            await insp.Ready(async (cli, token) =>
-            {
-                ctx = new DebugTestContext(cli, insp, token, scripts);
-
-                var bp = await SetBreakpoint("dotnet://debugger-test.dll/debugger-test.cs", 10, 8);
-                var bp2 = await SetBreakpoint("dotnet://debugger-test.dll/debugger-test.cs", 12, 8);
-                var pause_location = await EvaluateAndCheck(
-                    "window.setTimeout(function() { invoke_add(); invoke_add()}, 1);",
-                    "dotnet://debugger-test.dll/debugger-test.cs",  10, 8,
-                    "IntAdd");
-
-                Assert.Equal("other", pause_location["reason"]?.Value<string>());
-                Assert.Equal(bp.Value["breakpointId"]?.ToString(), pause_location["hitBreakpoints"]?[0]?.Value<string>());
-
-                await RemoveBreakpoint(bp.Value["breakpointId"]?.ToString());
-                await SendCommandAndCheck(JObject.FromObject(new { }), "Debugger.resume", "dotnet://debugger-test.dll/debugger-test.cs", 12, 8, "IntAdd");
-                await SendCommandAndCheck(JObject.FromObject(new { }), "Debugger.resume", "dotnet://debugger-test.dll/debugger-test.cs", 12, 8, "IntAdd");
-            });
-        }
-
-        [Fact]
-        public async Task CreateGoodBreakpointAndHitAndRemoveTwice()
-        {
-            var insp = new Inspector();
-
-            //Collect events
-            var scripts = SubscribeToScripts(insp);
-
-            await Ready();
-            await insp.Ready(async (cli, token) =>
-            {
-                ctx = new DebugTestContext(cli, insp, token, scripts);
-
-                var bp = await SetBreakpoint("dotnet://debugger-test.dll/debugger-test.cs", 10, 8);
-                var bp2 = await SetBreakpoint("dotnet://debugger-test.dll/debugger-test.cs", 12, 8);
-                var pause_location = await EvaluateAndCheck(
-                    "window.setTimeout(function() { invoke_add(); invoke_add()}, 1);",
-                    "dotnet://debugger-test.dll/debugger-test.cs",  10, 8,
-                    "IntAdd");
-
-                Assert.Equal("other", pause_location["reason"]?.Value<string>());
-                Assert.Equal(bp.Value["breakpointId"]?.ToString(), pause_location["hitBreakpoints"]?[0]?.Value<string>());
-
-                await RemoveBreakpoint(bp.Value["breakpointId"]?.ToString());
-                await RemoveBreakpoint(bp.Value["breakpointId"]?.ToString());
-            });
-        }
-
-        [Fact]
-        public async Task CreateGoodBreakpointAndHitAndRemoveAndDontHitAndCreateAgainAndHit()
-        {
-            var insp = new Inspector();
-
-            //Collect events
-            var scripts = SubscribeToScripts(insp);
-
-            await Ready();
-            await insp.Ready(async (cli, token) =>
-            {
-                ctx = new DebugTestContext(cli, insp, token, scripts);
-
-                var bp = await SetBreakpoint("dotnet://debugger-test.dll/debugger-test.cs", 10, 8);
-                var bp2 = await SetBreakpoint("dotnet://debugger-test.dll/debugger-test.cs", 12, 8);
-                var pause_location = await EvaluateAndCheck(
-                    "window.setTimeout(function() { invoke_add(); invoke_add(); invoke_add(); invoke_add()}, 1);",
-                    "dotnet://debugger-test.dll/debugger-test.cs",  10, 8,
-                    "IntAdd");
-
-                Assert.Equal("other", pause_location["reason"]?.Value<string>());
-                Assert.Equal(bp.Value["breakpointId"]?.ToString(), pause_location["hitBreakpoints"]?[0]?.Value<string>());
-
-                await RemoveBreakpoint(bp.Value["breakpointId"]?.ToString());
-                await SendCommandAndCheck(JObject.FromObject(new { }), "Debugger.resume", "dotnet://debugger-test.dll/debugger-test.cs", 12, 8, "IntAdd");
-                await SendCommandAndCheck(JObject.FromObject(new { }), "Debugger.resume", "dotnet://debugger-test.dll/debugger-test.cs", 12, 8, "IntAdd");
-                bp = await SetBreakpoint("dotnet://debugger-test.dll/debugger-test.cs", 10, 8);
-                await SendCommandAndCheck(JObject.FromObject(new { }), "Debugger.resume", "dotnet://debugger-test.dll/debugger-test.cs", 10, 8, "IntAdd");
-
-            });
-        }
-
-        [Fact]
         public async Task MulticastDelegateTest() => await CheckInspectLocalsAtBreakpointSite(
             "MulticastDelegateTestClass", "Test", 5, "Test",
             "window.setTimeout(function() { invoke_static_method('[debugger-test] MulticastDelegateTestClass:run'); })",
@@ -1816,33 +1018,6 @@ namespace DebuggerTests
                 AssertEqual(0, es_props.Values<JToken>().Count(), "es_props");
             });
 
-        [Fact]
-        public async Task StepOverAsyncMethod()
-        {
-            var insp = new Inspector();
-            //Collect events
-            var scripts = SubscribeToScripts(insp);
-
-            await Ready();
-            await insp.Ready(async (cli, token) =>
-            {
-                ctx = new DebugTestContext(cli, insp, token, scripts);
-
-                var bp = await SetBreakpointInMethod("debugger-test.dll", "AsyncStepClass", "TestAsyncStepOut2", 2);
-                System.Console.WriteLine(bp);
-                await EvaluateAndCheck(
-                    "window.setTimeout(function() { invoke_static_method_async('[debugger-test] AsyncStepClass:TestAsyncStepOut'); }, 1);",
-                    "dotnet://debugger-test.dll/debugger-async-step.cs", 19, 8,
-                    "MoveNext");
-
-                await StepAndCheck(StepKind.Over, "dotnet://debugger-test.dll/debugger-async-step.cs", 21, 8, "MoveNext");
-
-                await StepAndCheck(StepKind.Over, "dotnet://debugger-test.dll/debugger-async-step.cs", 22, 4, "MoveNext");
-
-                await StepAndCheck(StepKind.Over, null, 0, 0, "get_IsCompletedSuccessfully"); //not check the line number and the file name because this can be changed
-
-            });
-        }
 
         [Fact]
         public async Task PreviousFrameForAReflectedCall() => await CheckInspectLocalsAtBreakpointSite(
diff --git a/src/mono/wasm/debugger/tests/debugger-async-step.cs b/src/mono/wasm/debugger/tests/debugger-async-step.cs
deleted file mode 100644 (file)
index 18b519f..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-using System;
-using System.Threading.Tasks; 
-using System.Net; 
-using System.Net.Http;
-
-public class AsyncStepClass
-{
-    static HttpClient client = new HttpClient();
-    public static async Task TestAsyncStepOut()
-    {
-        await TestAsyncStepOut2("foobar");
-    }
-
-    public static async Task<int> TestAsyncStepOut2(string some)
-    {
-        var resp = await client.GetAsync("http://localhost:9400/debugger-driver.html");
-        Console.WriteLine($"resp: {resp}"); /// BP at this line
-
-        return 10;
-    }
-}
diff --git a/src/mono/wasm/debugger/tests/debugger-test/debugger-async-step.cs b/src/mono/wasm/debugger/tests/debugger-test/debugger-async-step.cs
new file mode 100644 (file)
index 0000000..f94cf8d
--- /dev/null
@@ -0,0 +1,60 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System;
+using System.Threading.Tasks;
+using System.Net;
+using System.Net.Http;
+
+namespace DebuggerTests
+{
+    public class AsyncStepClass
+    {
+        static HttpClient client = new HttpClient();
+        public static async Task TestAsyncStepOut()
+        {
+            await TestAsyncStepOut2("foobar");
+        }
+
+        public static async Task<int> TestAsyncStepOut2(string some)
+        {
+            var resp = await client.GetAsync("http://localhost:9400/debugger-driver.html");
+            Console.WriteLine($"resp: {resp}"); /// BP at this line
+
+            return 10;
+        }
+
+        public static void SimpleMethod()
+        {
+            var dt = new DateTime(4512, 1, 3, 5, 7, 9);
+            OtherMethod0(dt.AddMinutes(10));
+            Console.WriteLine ($"Back");
+        }
+
+        static void OtherMethod0(DateTime dt)
+        {
+            Console.WriteLine ($"dt: {dt}");
+            OtherMethod1();
+        }
+
+        static void OtherMethod1()
+        {
+            Console.WriteLine ($"In OtherMethod1");
+        }
+
+        public static async Task StepOverTestAsync()
+        {
+            await MethodWithTwoAwaitsAsync();
+            Console.WriteLine ($"StepOverTestAsync: done");
+        }
+
+        public static async Task MethodWithTwoAwaitsAsync()
+        {
+            Console.WriteLine ($"first await");
+            await Task.Delay(50);
+            Console.WriteLine ($"second await");
+            await Task.Delay(50);
+            Console.WriteLine ($"done");
+        }
+    }
+}
index 049b6b6..0e41730 100644 (file)
       <script async type="text/javascript" src="dotnet.js"></script>
          Stuff goes here
   </body>
-  </html> 
-     
-17  sdks/wasm/debugger-test.cs
-@@ -0,0 +1,17 @@
-using System;
-
-public class Math { //Only append content to this class as the test suite depends on line info
-       public static int IntAdd (int a, int b) {
-               int c = a + b;
-               int d = c + b;
-               int e = d + a;
-
-               return e;
-       }
-
-       public static int UseComplex () {
-               var complex = new Simple.Complex (10, "xx");
-               var res = complex.DoStuff ();
-               return res;
-       }
-}
-     
-19  sdks/wasm/debugger-test2.cs
-@@ -0,0 +1,19 @@
-using System;
-
-public class Misc { //Only append content to this class as the test suite depends on line info
-       public static int CreateObject (int foo, int bar) {
-               var f = new Fancy () {
-                       Foo = foo,
-                       Bar = bar,
-               };
-
-               Console.WriteLine ($"{f.Foo} {f.Bar}");
-               return f.Foo + f.Bar;
-       }
-}
-
-public class Fancy {
-       public int Foo;
-       public int Bar { get ; set; }
-}
+  </html>