test_browsing.py 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. """Browsing-related tests for the EventStreamRuntime, which connects to the RuntimeClient running in the sandbox."""
  2. import json
  3. import time
  4. from conftest import _load_runtime
  5. from openhands.core.logger import openhands_logger as logger
  6. from openhands.events.action import (
  7. BrowseInteractiveAction,
  8. BrowseURLAction,
  9. CmdRunAction,
  10. )
  11. from openhands.events.observation import (
  12. BrowserOutputObservation,
  13. CmdOutputObservation,
  14. )
  15. # ============================================================================================================================
  16. # Browsing tests
  17. # ============================================================================================================================
  18. PY3_FOR_TESTING = '/openhands/miniforge3/bin/mamba run -n base python3'
  19. def test_simple_browse(temp_dir, box_class, run_as_openhands):
  20. runtime = _load_runtime(temp_dir, box_class, run_as_openhands)
  21. # Test browse
  22. action_cmd = CmdRunAction(
  23. command=f'{PY3_FOR_TESTING} -m http.server 8000 > server.log 2>&1 &'
  24. )
  25. logger.info(action_cmd, extra={'msg_type': 'ACTION'})
  26. obs = runtime.run_action(action_cmd)
  27. logger.info(obs, extra={'msg_type': 'OBSERVATION'})
  28. assert isinstance(obs, CmdOutputObservation)
  29. assert obs.exit_code == 0
  30. assert '[1]' in obs.content
  31. action_cmd = CmdRunAction(command='sleep 3 && cat server.log')
  32. logger.info(action_cmd, extra={'msg_type': 'ACTION'})
  33. obs = runtime.run_action(action_cmd)
  34. logger.info(obs, extra={'msg_type': 'OBSERVATION'})
  35. assert obs.exit_code == 0
  36. action_browse = BrowseURLAction(url='http://localhost:8000')
  37. logger.info(action_browse, extra={'msg_type': 'ACTION'})
  38. obs = runtime.run_action(action_browse)
  39. logger.info(obs, extra={'msg_type': 'OBSERVATION'})
  40. assert isinstance(obs, BrowserOutputObservation)
  41. assert 'http://localhost:8000' in obs.url
  42. assert not obs.error
  43. assert obs.open_pages_urls == ['http://localhost:8000/']
  44. assert obs.active_page_index == 0
  45. assert obs.last_browser_action == 'goto("http://localhost:8000")'
  46. assert obs.last_browser_action_error == ''
  47. assert 'Directory listing for /' in obs.content
  48. assert 'server.log' in obs.content
  49. # clean up
  50. action = CmdRunAction(command='rm -rf server.log')
  51. logger.info(action, extra={'msg_type': 'ACTION'})
  52. obs = runtime.run_action(action)
  53. logger.info(obs, extra={'msg_type': 'OBSERVATION'})
  54. assert obs.exit_code == 0
  55. runtime.close(rm_all_containers=False)
  56. time.sleep(1)
  57. def test_browsergym_eval_env(box_class, temp_dir):
  58. runtime = _load_runtime(
  59. temp_dir,
  60. box_class=box_class,
  61. run_as_openhands=False, # need root permission to access file
  62. base_container_image='xingyaoww/od-eval-miniwob:v1.0',
  63. browsergym_eval_env='browsergym/miniwob.choose-list',
  64. )
  65. from openhands.runtime.browser.browser_env import (
  66. BROWSER_EVAL_GET_GOAL_ACTION,
  67. BROWSER_EVAL_GET_REWARDS_ACTION,
  68. )
  69. # Test browse
  70. action = BrowseInteractiveAction(browser_actions=BROWSER_EVAL_GET_GOAL_ACTION)
  71. logger.info(action, extra={'msg_type': 'ACTION'})
  72. obs = runtime.run_action(action)
  73. logger.info(obs, extra={'msg_type': 'OBSERVATION'})
  74. assert isinstance(obs, BrowserOutputObservation)
  75. assert not obs.error
  76. assert 'Select' in obs.content
  77. assert 'from the list and click Submit' in obs.content
  78. # Make sure the browser can produce observation in eva[l
  79. action = BrowseInteractiveAction(browser_actions='noop()')
  80. logger.info(action, extra={'msg_type': 'ACTION'})
  81. obs = runtime.run_action(action)
  82. logger.info(obs, extra={'msg_type': 'OBSERVATION'})
  83. assert (
  84. obs.url.strip()
  85. == 'file:///miniwob-plusplus/miniwob/html/miniwob/choose-list.html'
  86. )
  87. # Make sure the rewards are working
  88. action = BrowseInteractiveAction(browser_actions=BROWSER_EVAL_GET_REWARDS_ACTION)
  89. logger.info(action, extra={'msg_type': 'ACTION'})
  90. obs = runtime.run_action(action)
  91. logger.info(obs, extra={'msg_type': 'OBSERVATION'})
  92. assert json.loads(obs.content) == [0.0]
  93. runtime.close(rm_all_containers=False)
  94. time.sleep(1)