Example #1
0
 public SingleSessionTestBase(string driver = "debugger-driver.html") : base(driver)
 {
     insp    = new Inspector();
     scripts = SubscribeToScripts(insp);
 }
Example #2
0
        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
            });
        }
Example #3
0
        async Task AssemblyLoadedEventTest(string asm_name, string asm_path, string pdb_path, string source_file, int expected_count)
        {
            var insp    = new Inspector();
            var scripts = SubscribeToScripts(insp);

            int event_count = 0;
            var tcs         = new TaskCompletionSource <bool>();

            insp.On("Debugger.scriptParsed", async(args, c) =>
            {
                try
                {
                    var url = args["url"]?.Value <string>();
                    if (url?.EndsWith(source_file) == true)
                    {
                        event_count++;
                        if (event_count > expected_count)
                        {
                            tcs.SetResult(false);
                        }
                    }
                }
                catch (Exception ex)
                {
                    tcs.SetException(ex);
                }

                await Task.CompletedTask;
            });

            await Ready();

            await insp.Ready(async (cli, token) =>
            {
                ctx = new DebugTestContext(cli, insp, token, scripts);

                byte[] bytes      = File.ReadAllBytes(asm_path);
                string asm_base64 = Convert.ToBase64String(bytes);

                string pdb_base64 = String.Empty;
                if (pdb_path != null)
                {
                    bytes      = File.ReadAllBytes(pdb_path);
                    pdb_base64 = Convert.ToBase64String(bytes);
                }

                var expression = $@"MONO.mono_wasm_raise_debug_event({{
                    eventName: 'AssemblyLoaded',
                    assembly_name: '{asm_name}',
                    assembly_b64: '{asm_base64}',
                    pdb_b64: '{pdb_base64}'
                }});";

                var res = await ctx.cli.SendCommand($"Runtime.evaluate", JObject.FromObject(new { expression }), ctx.token);
                Assert.True(res.IsOk, $"Expected to pass for {expression}");

                res = await ctx.cli.SendCommand($"Runtime.evaluate", JObject.FromObject(new { expression }), ctx.token);
                Assert.True(res.IsOk, $"Expected to pass for {expression}");

                var t = await Task.WhenAny(tcs.Task, Task.Delay(2000));
                if (t.IsFaulted)
                {
                    throw t.Exception;
                }

                Assert.True(event_count <= expected_count, $"number of scriptParsed events received. Expected: {expected_count}, Actual: {event_count}");
            });
        }
Example #4
0
        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");
                }
                                   );
            });
        }
Example #5
0
        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
            });
        }
Example #6
0
        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");
                }
                                   );
            });
        }
Example #7
0
        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");
            });
        }
Example #8
0
        public async Task InspectLocalsDuringStepping()
        {
            var insp = new Inspector();
            //Collect events
            var scripts = SubscribeToScripts(insp);

            await Ready();

            await insp.Ready(async (cli, token) => {
                var bp1_req = JObject.FromObject(new {
                    lineNumber   = 4,
                    columnNumber = 2,
                    url          = dicFileToUrl["dotnet://debugger-test.dll/debugger-test.cs"],
                });

                var bp1_res = await cli.SendCommand("Debugger.setBreakpointByUrl", bp1_req, token);
                Assert.True(bp1_res.IsOk);

                var eval_req = JObject.FromObject(new {
                    expression = "window.setTimeout(function() { invoke_add(); }, 1);",
                });

                var eval_res = await cli.SendCommand("Runtime.evaluate", eval_req, token);
                Assert.True(eval_res.IsOk);

                var pause_location = await insp.WaitFor(Inspector.PAUSE);

                //ok, what's on that scope?
                var get_prop_req = JObject.FromObject(new {
                    objectId = "dotnet:scope:0",
                });

                var frame_props = await cli.SendCommand("Runtime.getProperties", get_prop_req, token);
                Assert.True(frame_props.IsOk);
                var locals = frame_props.Value ["result"];
                CheckNumber(locals, "a", 10);
                CheckNumber(locals, "b", 20);
                CheckNumber(locals, "c", 0);
                CheckNumber(locals, "d", 0);
                CheckNumber(locals, "e", 0);

                //step and get locals
                var step_res = await cli.SendCommand("Debugger.stepOver", null, token);
                Assert.True(step_res.IsOk);
                pause_location = await insp.WaitFor(Inspector.PAUSE);
                frame_props    = await cli.SendCommand("Runtime.getProperties", get_prop_req, token);
                Assert.True(frame_props.IsOk);

                locals = frame_props.Value ["result"];
                CheckNumber(locals, "a", 10);
                CheckNumber(locals, "b", 20);
                CheckNumber(locals, "c", 30);
                CheckNumber(locals, "d", 0);
                CheckNumber(locals, "e", 0);

                //step and get locals
                step_res = await cli.SendCommand("Debugger.stepOver", null, token);
                Assert.True(step_res.IsOk);
                pause_location = await insp.WaitFor(Inspector.PAUSE);
                frame_props    = await cli.SendCommand("Runtime.getProperties", get_prop_req, token);
                Assert.True(frame_props.IsOk);

                locals = frame_props.Value ["result"];
                CheckNumber(locals, "a", 10);
                CheckNumber(locals, "b", 20);
                CheckNumber(locals, "c", 30);
                CheckNumber(locals, "d", 50);
                CheckNumber(locals, "e", 0);
            });
        }
Example #9
0
        /*
         * 1. runs `Runtime.callFunctionOn` on the objectId,
         * if @roundtrip == false, then
         *     -> calls @test_fn for that result (new objectId)
         * else
         *     -> runs it again on the *result's* objectId.
         *        -> calls @test_fn on the *new* result objectId
         *
         * Returns: result of `Runtime.callFunctionOn`
         */
        async Task RunCallFunctionOn(string eval_fn, string fn_decl, string local_name, string bp_loc, int line, int col, int res_array_len = -1,
                                     Func <Result, Task> test_fn = null, bool returnByValue = false, JArray fn_args = null, bool roundtrip = false)
        {
            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(bp_loc, line, col);

                // callFunctionOn
                var eval_expr      = $"window.setTimeout(function() {{ {eval_fn} }}, 1);";
                var result         = await ctx.cli.SendCommand("Runtime.evaluate", JObject.FromObject(new { expression = eval_expr }), ctx.token);
                var pause_location = await ctx.insp.WaitFor(Inspector.PAUSE);

                // Um for js we get "scriptId": "6"
                // CheckLocation (bp_loc, line, col, ctx.scripts, pause_location ["callFrames"][0]["location"]);

                // Check the object at the bp
                var frame_locals = await GetProperties(pause_location ["callFrames"][0]["scopeChain"][0]["object"]["objectId"].Value <string> ());
                var obj          = GetAndAssertObjectWithName(frame_locals, local_name);
                var obj_id       = obj ["value"]["objectId"].Value <string> ();

                var cfo_args = JObject.FromObject(new {
                    functionDeclaration = fn_decl,
                    objectId            = obj_id
                });

                if (fn_args != null)
                {
                    cfo_args ["arguments"] = fn_args;
                }

                if (returnByValue)
                {
                    cfo_args ["returnByValue"] = returnByValue;
                }

                // callFunctionOn
                result = await ctx.cli.SendCommand("Runtime.callFunctionOn", cfo_args, ctx.token);
                await CheckCFOResult(result);

                // If it wasn't `returnByValue`, then try to run a new function
                // on that *returned* object
                // This second function, just returns the object as-is, so the same
                // test_fn is re-usable.
                if (!returnByValue && roundtrip)
                {
                    cfo_args = JObject.FromObject(new {
                        functionDeclaration = "function () { return this; }",
                        objectId            = result.Value ["result"]["objectId"]?.Value <string> ()
                    });

                    if (fn_args != null)
                    {
                        cfo_args ["arguments"] = fn_args;
                    }

                    result = await ctx.cli.SendCommand("Runtime.callFunctionOn", cfo_args, ctx.token);

                    await CheckCFOResult(result);
                }

                if (test_fn != null)
                {
                    await test_fn(result);
                }

                return;

                async Task CheckCFOResult(Result result)
                {
                    if (returnByValue)
                    {
                        return;
                    }

                    if (res_array_len < 0)
                    {
                        await CheckValue(result.Value ["result"], TObject("Object"), $"cfo-res");
                    }
                    else
                    {
                        await CheckValue(result.Value ["result"], TArray("Array", res_array_len), $"cfo-res");
                    }
                }
            });
        }
Example #10
0
 public BadHarnessInitTests(string driver = "debugger-driver.html") : base(driver)
 {
     insp    = new Inspector();
     scripts = SubscribeToScripts(insp);
 }