def test_log_on_breakpoint(debugger_api: _DebuggerAPI): from robocorp_ls_core.debug_adapter_core.dap.dap_schema import TerminatedEvent from robocorp_ls_core.debug_adapter_core.dap.dap_schema import OutputEvent debugger_api.initialize() target = debugger_api.get_dap_case_file("case_condition.robot") debugger_api.target = target debugger_api.launch(target, debug=True) line = debugger_api.get_line_index_with_content("Log ${counter}") debugger_api.set_breakpoints( target, line, line_to_kwargs={line: { "logMessage": "Counter is: ${counter}" }}) debugger_api.configuration_done() debugger_api.read(TerminatedEvent) debugger_api.assert_message_found( OutputEvent, accept_msg=lambda output: output.body.output.strip() == "Counter is: 1", ) debugger_api.assert_message_found( OutputEvent, accept_msg=lambda output: output.body.output.strip() == "Counter is: 2", )
def test_error_handling(debugger_api: _DebuggerAPI): """ This is an integrated test of the debug adapter. It communicates with it as if it was VSCode. """ from robocorp_ls_core.debug_adapter_core.dap.dap_schema import TerminatedEvent from robocorp_ls_core.debug_adapter_core.dap.dap_schema import Response from robocorp_ls_core.debug_adapter_core.dap.dap_schema import Request debugger_api.initialize() target = debugger_api.get_dap_case_file("case_log.robot") debugger_api.launch(target, debug=True) # Let's write some invalid messages... debugger_api.write({}) response = debugger_api.read(Response) assert not response.success debugger_api.write(Request("invalid_command")) response = debugger_api.read(Response) assert not response.success debugger_api.set_breakpoints(target, 4) debugger_api.configuration_done() debugger_api.wait_for_thread_stopped() debugger_api.continue_event() debugger_api.read(TerminatedEvent)
def test_stop_on_hit_condition(debugger_api: _DebuggerAPI): from robocorp_ls_core.debug_adapter_core.dap.dap_schema import TerminatedEvent debugger_api.initialize() target = debugger_api.get_dap_case_file("case_condition.robot") debugger_api.target = target debugger_api.launch(target, debug=True) line = debugger_api.get_line_index_with_content("Log ${counter}") debugger_api.set_breakpoints(target, line, line_to_kwargs={line: { "hitCondition": "2" }}) debugger_api.configuration_done() json_hit = debugger_api.wait_for_thread_stopped(name="Log") name_to_scope = debugger_api.get_name_to_scope(json_hit.frame_id) assert sorted( name_to_scope.keys()) == ["Arguments", "Builtins", "Variables"] name_to_var = debugger_api.get_variables_name_to_var(json_hit.frame_id) assert name_to_var["'${counter}'"].value == "2" msg = debugger_api.continue_event(json_hit.thread_id, accept_terminated=True) if not isinstance(msg, TerminatedEvent): debugger_api.read(TerminatedEvent)
def test_simple_debug_launch_stop_on_robot_and_pydevd( debugger_api: _DebuggerAPI): from robocorp_ls_core.debug_adapter_core.dap.dap_schema import TerminatedEvent from robocorp_ls_core.debug_adapter_core.dap.dap_schema import ThreadsResponse debugger_api.initialize() target = debugger_api.get_dap_case_file("case_python.robot") debugger_api.target = target mypylib = debugger_api.get_dap_case_file("mypylib.py") debugger_api.launch(target, debug=True) threads_response: ThreadsResponse = (debugger_api.list_threads()) assert len(threads_response.body.threads) == 1 bp_robot = debugger_api.get_line_index_with_content("Some Call") bp_pydevd = debugger_api.get_line_index_with_content("break here", filename=mypylib) debugger_api.set_breakpoints(target, bp_robot) debugger_api.set_breakpoints(mypylib, bp_pydevd) debugger_api.configuration_done() json_hit = debugger_api.wait_for_thread_stopped(file="case_python.robot") msg = debugger_api.continue_event(json_hit.thread_id) debugger_api.wait_for_thread_stopped(file="mypylib.py") msg = debugger_api.continue_event(json_hit.thread_id, accept_terminated=True) if not isinstance(msg, TerminatedEvent): debugger_api.read(TerminatedEvent)
def test_evaluate(debugger_api: _DebuggerAPI): from robocorp_ls_core.debug_adapter_core.dap.dap_schema import TerminatedEvent debugger_api.initialize() target = debugger_api.get_dap_case_file("case_evaluate.robot") debugger_api.target = target debugger_api.launch(target, debug=True) debugger_api.set_breakpoints( target, debugger_api.get_line_index_with_content("Break 1")) debugger_api.configuration_done() json_hit = debugger_api.wait_for_thread_stopped(name="Should Be Equal") response = debugger_api.evaluate("${arg1}", frameId=json_hit.frame_id, context="watch") assert response.body.result == "2" response = debugger_api.evaluate("My Equal Redefined 2 2", frameId=json_hit.frame_id, context="repl") assert response.body.result == "None" assert json_hit.stack_trace_response.body.stackFrames[0][ "id"] == json_hit.frame_id response = debugger_api.evaluate( "My Equal Redefined 2 1", frameId=json_hit.frame_id, context="repl", success=False, ) assert "UserKeywordExecutionFailed: 2 != 1" in response.message # We can't evaluate keywords that are not in the top level. parent_frame_id = json_hit.stack_trace_response.body.stackFrames[1]["id"] response = debugger_api.evaluate( "My Equal Redefined 2 2", frameId=parent_frame_id, context="repl", success=False, ) assert ("Keyword calls may only be evaluated at the topmost frame" in response.message) debugger_api.set_breakpoints( target, debugger_api.get_line_index_with_content("Break 2")) debugger_api.continue_event() json_hit = debugger_api.wait_for_thread_stopped(name="Should Be Equal") response = debugger_api.evaluate("${arg1}", frameId=json_hit.frame_id, context="watch") assert response.body.result in ("['2', '2']", "[u'2', u'2']") debugger_api.continue_event() debugger_api.read(TerminatedEvent)
def test_launch_in_external_terminal(debugger_api: _DebuggerAPI): """ This is an integrated test of the debug adapter. It communicates with it as if it was VSCode. """ from robocorp_ls_core.debug_adapter_core.dap.dap_schema import TerminatedEvent debugger_api.initialize() target = debugger_api.get_dap_case_file("case_log.robot") debugger_api.launch(target, debug=False, terminal="external") debugger_api.configuration_done() debugger_api.read(TerminatedEvent)
def test_simple_launch(debugger_api: _DebuggerAPI): """ This is an integrated test of the debug adapter. It communicates with it as if it was VSCode. """ from robocorp_ls_core.debug_adapter_core.dap.dap_schema import TerminatedEvent from robocorp_ls_core.debug_adapter_core.dap.dap_schema import OutputEvent debugger_api.initialize() target = debugger_api.get_dap_case_file("case_log.robot") debugger_api.launch(target, debug=False) debugger_api.configuration_done() debugger_api.read(TerminatedEvent) debugger_api.assert_message_found( OutputEvent, lambda msg: "check that log works" in msg.body.output)
def test_variables(debugger_api: _DebuggerAPI): from robocorp_ls_core.debug_adapter_core.dap.dap_schema import TerminatedEvent debugger_api.initialize() target = debugger_api.get_dap_case_file("case4/case4.robot") debugger_api.target = target debugger_api.launch(target, debug=True, args=["--variable", "my_var:22"]) debugger_api.set_breakpoints( target, debugger_api.get_line_index_with_content("My Equal Redefined 2 2")) debugger_api.configuration_done() json_hit = debugger_api.wait_for_thread_stopped(name="My Equal Redefined") name_to_scope = debugger_api.get_name_to_scope(json_hit.frame_id) assert sorted( name_to_scope.keys()) == ["Arguments", "Builtins", "Variables"] name_to_var = debugger_api.get_arguments_name_to_var(json_hit.frame_id) assert sorted(name_to_var.keys()) == ["Arg 0", "Arg 1"] name_to_var = debugger_api.get_variables_name_to_var(json_hit.frame_id) assert "'${TEST_NAME}'" not in name_to_var assert "'${arg1}'" not in name_to_var assert "'${my_var}'" in name_to_var name_to_var = debugger_api.get_builtins_name_to_var(json_hit.frame_id) assert "'${TEST_NAME}'" in name_to_var assert "'${arg1}'" not in name_to_var assert "'${my_var}'" not in name_to_var debugger_api.step_in(json_hit.thread_id) # Check that the 'arg1' var is in the current namespace but not in the parent # namespace. json_hit = debugger_api.wait_for_thread_stopped("step", name="Should Be Equal") name_to_var = debugger_api.get_variables_name_to_var(json_hit.frame_id) assert "'${arg1}'" in name_to_var or "u'${arg1}'" in name_to_var name_to_var = debugger_api.get_variables_name_to_var( json_hit.stack_trace_response.body.stackFrames[1]["id"]) assert "'${arg1}'" not in name_to_var and "u'${arg1}'" not in name_to_var debugger_api.continue_event() debugger_api.read(TerminatedEvent)
def test_simple_debug_launch(debugger_api: _DebuggerAPI): from robocorp_ls_core.debug_adapter_core.dap.dap_schema import TerminatedEvent debugger_api.initialize() target = debugger_api.get_dap_case_file("case_log.robot") debugger_api.launch(target, debug=True) threads_response = (debugger_api.list_threads() ) #: :type thread_response: ThreadsResponse assert len(threads_response.body.threads) == 1 debugger_api.set_breakpoints(target, 4) debugger_api.configuration_done() debugger_api.wait_for_thread_stopped() debugger_api.continue_event() debugger_api.read(TerminatedEvent)
def test_simple_debug_launch_stop_on_robot(debugger_api: _DebuggerAPI): from robocorp_ls_core.debug_adapter_core.dap.dap_schema import TerminatedEvent from robocorp_ls_core.debug_adapter_core.dap.dap_schema import ThreadsResponse debugger_api.initialize() target = debugger_api.get_dap_case_file("case_log.robot") debugger_api.launch(target, debug=True) threads_response: ThreadsResponse = (debugger_api.list_threads()) assert len(threads_response.body.threads) == 1 thread = next(iter(threads_response.body.threads)) debugger_api.set_breakpoints(target, 4) debugger_api.configuration_done() json_hit = debugger_api.wait_for_thread_stopped(file="case_log.robot") assert json_hit.thread_id == thread["id"] debugger_api.continue_event(json_hit.thread_id) debugger_api.read(TerminatedEvent)
def test_step_out(debugger_api: _DebuggerAPI): from robocorp_ls_core.debug_adapter_core.dap.dap_schema import TerminatedEvent debugger_api.initialize() target = debugger_api.get_dap_case_file("case_step_out.robot") debugger_api.target = target debugger_api.launch(target, debug=True) debugger_api.set_breakpoints( target, debugger_api.get_line_index_with_content("Break 1")) debugger_api.configuration_done() json_hit = debugger_api.wait_for_thread_stopped(name="Should Be Equal") debugger_api.step_out(json_hit.thread_id) json_hit = debugger_api.wait_for_thread_stopped( "step", name="Yet Another Equal Redefined") debugger_api.continue_event() debugger_api.read(TerminatedEvent)
def test_init_auto_loaded(debugger_api: _DebuggerAPI): from robocorp_ls_core.debug_adapter_core.dap.dap_schema import TerminatedEvent debugger_api.initialize() target = debugger_api.get_dap_case_file("check_init/lsp_test.robot") target_init = debugger_api.get_dap_case_file("check_init/__init__.robot") debugger_api.target = target debugger_api.launch(target, debug=True) bp_setup = debugger_api.get_line_index_with_content("Suite Setup", filename=target_init) bp_teardown = debugger_api.get_line_index_with_content( "Suite Teardown", filename=target_init) debugger_api.set_breakpoints(target_init, (bp_setup, bp_teardown)) debugger_api.configuration_done() json_hit = debugger_api.wait_for_thread_stopped(file="__init__.robot") debugger_api.continue_event(json_hit.thread_id) json_hit = debugger_api.wait_for_thread_stopped(file="__init__.robot") debugger_api.continue_event(json_hit.thread_id) debugger_api.read(TerminatedEvent)
def test_invalid_launch_1(debugger_api: _DebuggerAPI): from robocorp_ls_core.debug_adapter_core.dap.dap_schema import LaunchRequest from robocorp_ls_core.debug_adapter_core.dap.dap_schema import LaunchRequestArguments from robocorp_ls_core.debug_adapter_core.dap.dap_schema import Response debugger_api.initialize() debugger_api.write( LaunchRequest( LaunchRequestArguments( __sessionId="some_id", noDebug=True, # target=target, -- error: don't add target terminal="none", cwd=None, ))) launch_response = debugger_api.read(Response) assert launch_response.success == False