text: from subprocess import call
  from os import path
  import hitchpostgres
  import hitchselenium
  import hitchpython
  import hitchserve
  import hitchredis
  import hitchtest
  import hitchsmtp
  
  
  # Get directory above this file
  PROJECT_DIRECTORY = path.abspath(path.join(path.dirname(__file__), '..'))
  
  
  class ExecutionEngine(hitchtest.ExecutionEngine):
      """Engine for orchestating and interacting with the app."""
  
      def set_up(self):
          """Ensure virtualenv present, then run all services."""
          python_package = hitchpython.PythonPackage(
              python_version=self.preconditions['python_version']
          )
          python_package.build()
          python_package.verify()
  
          call([
              python_package.pip, "install", "-r",
              path.join(PROJECT_DIRECTORY, "requirements/local.txt")
          ])
  
          postgres_package = hitchpostgres.PostgresPackage(
              version=self.settings["postgres_version"],
          )
          postgres_package.build()
          postgres_package.verify()
  
          redis_package = hitchredis.RedisPackage(version="2.8.4")
          redis_package.build()
          redis_package.verify()
  
          self.services = hitchserve.ServiceBundle(
              project_directory=PROJECT_DIRECTORY,
              startup_timeout=float(self.settings["startup_timeout"]),
              shutdown_timeout=5.0,
          )
  
          postgres_user = hitchpostgres.PostgresUser("kickass", "password")
  
          self.services['Postgres'] = hitchpostgres.PostgresService(
              postgres_package=postgres_package,
              users=[postgres_user, ],
              databases=[hitchpostgres.PostgresDatabase("kickass", postgres_user), ]
          )
  
          self.services['HitchSMTP'] = hitchsmtp.HitchSMTPService(port=1025)
  
          self.services['Django'] = hitchpython.DjangoService(
              python=python_package.python,
              port=8000,
              version=str(self.settings.get("django_version")),
              settings="config.settings.local",
              needs=[self.services['Postgres'], ],
              env_vars=self.settings['environment_variables'],
          )
  
          self.services['Redis'] = hitchredis.RedisService(
              redis_package=redis_package,
              port=16379,
          )
  
          self.services['Firefox'] = hitchselenium.SeleniumService(
              xvfb=self.settings.get("quiet", False),
              no_libfaketime=True,
          )
  
  #        import hitchcron
  #        self.services['Cron'] = hitchcron.CronService(
  #            run=self.services['Django'].manage("trigger").command,
  #            every=1,
  #            needs=[ self.services['Django'], ],
  #        )
  
          self.services.startup(interactive=False)
  
          # Configure selenium driver
          self.driver = self.services['Firefox'].driver
          self.driver.set_window_size(self.settings['window_size']['height'], self.settings['window_size']['width'])
          self.driver.set_window_position(0, 0)
          self.driver.implicitly_wait(2.0)
          self.driver.accept_next_alert = True
  
      def pause(self, message=None):
          """Stop. IPython time."""
          if hasattr(self, 'services'):
              self.services.start_interactive_mode()
          self.ipython(message)
          if hasattr(self, 'services'):
              self.services.stop_interactive_mode()
  
      def load_website(self):
          """Navigate to website in Firefox."""
          self.driver.get(self.services['Django'].url())
  
      def click(self, on):
          """Click on HTML id."""
          self.driver.find_element_by_id(on).click()
  
      def fill_form(self, **kwargs):
          """Fill in a form with id=value."""
          for element, text in kwargs.items():
              self.driver.find_element_by_id(element).send_keys(text)
  
      def click_submit(self):
          """Click on a submit button if it exists."""
          self.driver.find_element_by_css_selector("button[type=\"submit\"]").click()
  
      def confirm_emails_sent(self, number):
          """Count number of emails sent by app."""
          assert len(self.services['HitchSMTP'].logs.json()) == int(number)
  
      def wait_for_email(self, containing=None):
          """Wait for, and return email."""
          self.services['HitchSMTP'].logs.out.tail.until_json(
              lambda email: containing in email['payload'] or containing in email['subject'],
              timeout=25,
              lines_back=1,
          )
  
      def time_travel(self, days=""):
          """Make all services think that time has skipped forward."""
          self.services.time_travel(days=int(days))
  
      def on_failure(self):
          """Stop and IPython."""
          if not self.settings['quiet']:
              if self.settings.get("pause_on_failure", False):
                  self.pause(message=self.stacktrace.to_template())
  
      def on_success(self):
          """Pause on success if enabled."""
          if self.settings.get("pause_on_success", False):
              self.pause(message="SUCCESS")
  
      def tear_down(self):
          """Shut down services required to run your test."""
          if hasattr(self, 'services'):
              self.services.shutdown()
  