content: import os
  from time import sleep
  
  from dash.testing.wait import until
  
  from dash import Dash, Input, Output, html
  from dash.exceptions import PreventUpdate
  
  
  RED_BG = """
  #hot-reload-content {
      background-color: red;
  }
  """
  
  GOUDA = """
  window.cheese = 'gouda';
  """
  
  
  def replace_file(filename, new_content):
      path = os.path.join(os.path.dirname(__file__), "hr_assets", filename)
      with open(path, "r+") as fp:
          sleep(1)  # ensure a new mod time
          old_content = fp.read()
          fp.truncate(0)
          fp.seek(0)
          fp.write(new_content)
  
      return path, old_content
  
  
  def test_dvhr001_hot_reload(dash_duo_mp):
      app = Dash(__name__, assets_folder="hr_assets")
      app.layout = html.Div(
          [html.H3("Hot reload", id="text"), html.Button("Click", id="btn")],
          id="hot-reload-content",
      )
  
      @app.callback(Output("text", "children"), [Input("btn", "n_clicks")])
      def new_text(n):
          if not n:
              raise PreventUpdate
          return n
  
      hot_reload_settings = dict(
          dev_tools_hot_reload=True,
          dev_tools_ui=True,
          dev_tools_serve_dev_bundles=True,
          dev_tools_hot_reload_interval=0.1,
          dev_tools_hot_reload_max_retry=100,
      )
  
      dash_duo_mp.start_server(app, **hot_reload_settings)
  
      # default overload color is blue
      dash_duo_mp.wait_for_style_to_equal(
          "#hot-reload-content", "background-color", "rgba(0, 0, 255, 1)"
      )
  
      # set a global var - if we soft reload it should still be there,
      # hard reload will delete it
      dash_duo_mp.driver.execute_script("window.someVar = 42;")
      assert dash_duo_mp.driver.execute_script("return window.someVar") == 42
  
      soft_reload_file, old_soft = replace_file("hot_reload.css", RED_BG)
  
      try:
          # red is live changed during the test execution
          dash_duo_mp.wait_for_style_to_equal(
              "#hot-reload-content", "background-color", "rgba(255, 0, 0, 1)"
          )
      finally:
          sleep(1)  # ensure a new mod time
          with open(soft_reload_file, "w") as f:
              f.write(old_soft)
  
      dash_duo_mp.wait_for_style_to_equal(
          "#hot-reload-content", "background-color", "rgba(0, 0, 255, 1)"
      )
  
      # only soft reload, someVar is still there
      assert dash_duo_mp.driver.execute_script("return window.someVar") == 42
  
      assert dash_duo_mp.driver.execute_script("return window.cheese") == "roquefort"
  
      hard_reload_file, old_hard = replace_file("hot_reload.js", GOUDA)
  
      try:
          until(
              lambda: dash_duo_mp.driver.execute_script("return window.cheese")
              == "gouda",
              timeout=10,
          )
      finally:
          sleep(1)  # ensure a new mod time
          with open(hard_reload_file, "w") as f:
              f.write(old_hard)
  
      until(
          lambda: dash_duo_mp.driver.execute_script("return window.cheese")
          == "roquefort",
          timeout=10,
      )
  
      # we've done a hard reload so someVar is gone
      assert dash_duo_mp.driver.execute_script("return window.someVar") is None
  
      # Now check the server status indicator functionality
      dash_duo_mp.find_element(".dash-debug-menu__button--available")
      sleep(1)  # wait for opening animation
      dash_duo_mp.percy_snapshot(name="hot-reload-available")
  
      dash_duo_mp.server.stop()
      sleep(1)
      dash_duo_mp.wait_for_element(".dash-debug-menu__button--unavailable")
      dash_duo_mp.wait_for_no_elements(".dash-fe-error__title")
      dash_duo_mp.percy_snapshot(name="hot-reload-unavailable")
      dash_duo_mp.percy_snapshot(name="hot-reload-unavailable-small")
  
      dash_duo_mp.find_element("#btn").click()
      dash_duo_mp.wait_for_text_to_equal(
          ".dash-fe-error__title", "Callback failed: the server did not respond."
      )
  
      # start up the server again
      dash_duo_mp.start_server(app, **hot_reload_settings)
  
      # rerenders with debug menu closed after reload
      # reopen and check that server is now available
      dash_duo_mp.find_element(".dash-debug-menu__button--available")
  