def set_up(self): """Ensure python environment present, then run all services.""" python_package = hitchpython.PythonPackage( python_version=self.settings['python_version'], directory=path.join( PROJECT_DIRECTORY, "pyv{}".format( self.settings['python_version'] ) ) ) python_package.build() python_package.verify() call([ python_package.pip, "install", "-r", path.join(PROJECT_DIRECTORY, "requirements.txt") ]) postgres_package = hitchpostgres.PostgresPackage( version=self.settings["postgres_version"], ) postgres_package.build() postgres_package.verify() self.services = ServiceBundle( project_directory=PROJECT_DIRECTORY, startup_timeout=float(self.settings["startup_timeout"]), shutdown_timeout=5.0, ) postgres_user = hitchpostgres.PostgresUser("patrycja", "mypassword") self.services['Postgres'] = hitchpostgres.PostgresService( port=5432, postgres_package=postgres_package, users=[postgres_user, ], databases=[hitchpostgres.PostgresDatabase("todoapp", postgres_user), ] ) self.services['Flask'] = FlaskService( python=python_package.python, needs=[self.services['Postgres'],] ) self.services['Firefox'] = hitchselenium.SeleniumService( xvfb=self.settings.get("xvfb", False) or self.settings.get("quiet", False), no_libfaketime=True, ) self.services.startup(interactive=False) # Configure selenium driver self.driver = self.services['Firefox'].driver self.driver.set_window_size(800, 600) self.driver.set_window_position(0, 0) self.driver.implicitly_wait(2.0) self.driver.accept_next_alert = True
def set_up(self): """Set up your applications and the test environment.""" # COMPILE YOUR C++ APPLICATION HERE #check_call(["make"]) postgres_package = hitchpostgres.PostgresPackage( version=self.preconditions["postgres_version"], ) postgres_package.build() self.services = ServiceBundle( project_directory=PROJECT_DIRECTORY, startup_timeout=float(self.settings["startup_timeout"]), shutdown_timeout=float(self.settings["shutdown_timeout"]), ) # Create postgres user and database postgres_user = hitchpostgres.PostgresUser("example", "password") self.services['Postgres'] = hitchpostgres.PostgresService( postgres_package=postgres_package, users=[postgres_user, ], databases=[hitchpostgres.PostgresDatabase("example", postgres_user), ] ) self.services.startup(interactive=False) self.cli_steps = hitchcli.CommandLineStepLibrary(default_timeout=90) self.cd = self.cli_steps.cd self.run = self.cli_steps.run self.expect = self.cli_steps.expect self.send_control = self.cli_steps.send_control self.send_line = self.cli_steps.send_line self.exit_with_any_code = self.cli_steps.exit_with_any_code self.exit = self.cli_steps.exit chdir(PROJECT_DIRECTORY)
class ExecutionEngine(hitchtest.ExecutionEngine): """Python engine for running tests.""" def set_up(self): """Set up your applications and the test environment.""" # COMPILE YOUR C++ APPLICATION HERE #check_call(["make"]) postgres_package = hitchpostgres.PostgresPackage( version=self.preconditions["postgres_version"], ) postgres_package.build() self.services = ServiceBundle( project_directory=PROJECT_DIRECTORY, startup_timeout=float(self.settings["startup_timeout"]), shutdown_timeout=float(self.settings["shutdown_timeout"]), ) # Create postgres user and database postgres_user = hitchpostgres.PostgresUser("example", "password") self.services['Postgres'] = hitchpostgres.PostgresService( postgres_package=postgres_package, users=[postgres_user, ], databases=[hitchpostgres.PostgresDatabase("example", postgres_user), ] ) self.services.startup(interactive=False) self.cli_steps = hitchcli.CommandLineStepLibrary(default_timeout=90) self.cd = self.cli_steps.cd self.run = self.cli_steps.run self.expect = self.cli_steps.expect self.send_control = self.cli_steps.send_control self.send_line = self.cli_steps.send_line self.exit_with_any_code = self.cli_steps.exit_with_any_code self.exit = self.cli_steps.exit chdir(PROJECT_DIRECTORY) def run_sql(self, sql=None, database=None): self.services['Postgres'].databases[0].psql(sql) def pause(self, message=None): """Pause test and launch IPython""" if hasattr(self, 'services'): self.services.start_interactive_mode() self.ipython(message) if hasattr(self, 'services'): self.services.stop_interactive_mode() def time_travel(self, days=""): """Move Postgres forward in time""" self.services.time_travel(days=int(days)) def connect_to_kernel(self, service_name): """Connect to IPython kernel embedded in service_name.""" self.services.connect_to_ipykernel(service_name) def on_failure(self): """Runs if there is a test failure""" if not self.settings['quiet']: if self.settings.get("pause_on_failure", False): self.pause(message=self.stacktrace.to_template()) def on_success(self): """Runs when a test successfully passes""" if self.settings.get("pause_on_success", False): self.pause(message="SUCCESS") def tear_down(self): """Run at the end of all tests.""" if hasattr(self, 'services'): self.services.shutdown()
def set_up(self): """Set up your applications and the test environment.""" self.python_package = hitchpython.PythonPackage( python_version=self.settings['python_version'] ) self.python_package.build() self.python_package.verify() check_call([ self.python_package.pip, "install", "-r", path.join(PROJECT_DIRECTORY, "requirements.txt") ]) self.turkeydb_file = path.join(hitchtest.utils.get_hitch_directory(), "turkey-test.db") self.turkeydb_file_pre_existing = True self.turkey_conf_file = path.join(PROJECT_DIRECTORY, "turkey-test.conf") assert not path.exists(self.turkeydb_file), ( "Test turkeyDB already exists at {path}, " "please move or delete.".format( path=self.turkeydb_file, ) ) self.turkeydb_file_pre_existing = False with open(self.turkey_conf_file, "w") as turkey_conf: turkey_conf.write(json.dumps({ "SECRET_KEY": "xxx", "LISTEN_IP": "127.0.0.1", "LISTEN_PORT": 5000, "DEBUG": False, "SQLALCHEMY_TRACK_MODIFICATIONS": False, "SQLALCHEMY_DATABASE_URI": "sqlite:///{}".format(self.turkeydb_file) })) chdir(PROJECT_DIRECTORY) check_call([self.python_package.python, "manage.py", "db", "upgrade"]) self.services = ServiceBundle( project_directory=PROJECT_DIRECTORY, startup_timeout=float(self.settings["startup_timeout"]), shutdown_timeout=float(self.settings["shutdown_timeout"]), ) # Docs : https://hitchtest.readthedocs.org/en/latest/plugins/hitchsmtp.html self.services['HitchSMTP'] = hitchsmtp.HitchSMTPService(port=10025) # Docs : https://hitchtest.readthedocs.org/en/latest/plugins/hitchpython.html self.services['Flask'] = hitchserve.Service( command=[self.python_package.python, "manage.py", "runserver", ], directory=PROJECT_DIRECTORY, needs=[], log_line_ready_checker=lambda line: "Running on" in line, ) # Docs : https://hitchtest.readthedocs.org/en/latest/plugins/hitchselenium.html self.services['Firefox'] = hitchselenium.SeleniumService( xvfb=self.settings.get("xvfb", False) or self.settings.get("quiet", False), no_libfaketime=True, ) self.services.startup(interactive=False) # Docs : https://hitchtest.readthedocs.org/en/latest/plugins/hitchselenium.html self.driver = self.services['Firefox'].driver self.webapp = hitchselenium.SeleniumStepLibrary( selenium_webdriver=self.driver, wait_for_timeout=5, ) self.click = self.webapp.click self.should_not_appear = self.webapp.should_not_appear self.wait_to_appear = self.webapp.wait_to_appear self.wait_to_contain = self.webapp.wait_to_contain self.wait_for_any_to_contain = self.webapp.wait_for_any_to_contain self.click_and_dont_wait_for_page_load = self.webapp.click_and_dont_wait_for_page_load # Configure selenium driver screen_res = self.settings.get( "screen_resolution", {"width": 1024, "height": 768, } ) self.driver.set_window_size( int(screen_res['width']), int(screen_res['height']) ) self.driver.set_window_position(0, 0) self.driver.implicitly_wait(2.0) self.driver.accept_next_alert = True chdir(PROJECT_DIRECTORY)
class ExecutionEngine(hitchtest.ExecutionEngine): """Python engine for running tests.""" def set_up(self): """Set up your applications and the test environment.""" self.python_package = hitchpython.PythonPackage( python_version=self.settings['python_version'] ) self.python_package.build() self.python_package.verify() check_call([ self.python_package.pip, "install", "-r", path.join(PROJECT_DIRECTORY, "requirements.txt") ]) self.turkeydb_file = path.join(hitchtest.utils.get_hitch_directory(), "turkey-test.db") self.turkeydb_file_pre_existing = True self.turkey_conf_file = path.join(PROJECT_DIRECTORY, "turkey-test.conf") assert not path.exists(self.turkeydb_file), ( "Test turkeyDB already exists at {path}, " "please move or delete.".format( path=self.turkeydb_file, ) ) self.turkeydb_file_pre_existing = False with open(self.turkey_conf_file, "w") as turkey_conf: turkey_conf.write(json.dumps({ "SECRET_KEY": "xxx", "LISTEN_IP": "127.0.0.1", "LISTEN_PORT": 5000, "DEBUG": False, "SQLALCHEMY_TRACK_MODIFICATIONS": False, "SQLALCHEMY_DATABASE_URI": "sqlite:///{}".format(self.turkeydb_file) })) chdir(PROJECT_DIRECTORY) check_call([self.python_package.python, "manage.py", "db", "upgrade"]) self.services = ServiceBundle( project_directory=PROJECT_DIRECTORY, startup_timeout=float(self.settings["startup_timeout"]), shutdown_timeout=float(self.settings["shutdown_timeout"]), ) # Docs : https://hitchtest.readthedocs.org/en/latest/plugins/hitchsmtp.html self.services['HitchSMTP'] = hitchsmtp.HitchSMTPService(port=10025) # Docs : https://hitchtest.readthedocs.org/en/latest/plugins/hitchpython.html self.services['Flask'] = hitchserve.Service( command=[self.python_package.python, "manage.py", "runserver", ], directory=PROJECT_DIRECTORY, needs=[], log_line_ready_checker=lambda line: "Running on" in line, ) # Docs : https://hitchtest.readthedocs.org/en/latest/plugins/hitchselenium.html self.services['Firefox'] = hitchselenium.SeleniumService( xvfb=self.settings.get("xvfb", False) or self.settings.get("quiet", False), no_libfaketime=True, ) self.services.startup(interactive=False) # Docs : https://hitchtest.readthedocs.org/en/latest/plugins/hitchselenium.html self.driver = self.services['Firefox'].driver self.webapp = hitchselenium.SeleniumStepLibrary( selenium_webdriver=self.driver, wait_for_timeout=5, ) self.click = self.webapp.click self.should_not_appear = self.webapp.should_not_appear self.wait_to_appear = self.webapp.wait_to_appear self.wait_to_contain = self.webapp.wait_to_contain self.wait_for_any_to_contain = self.webapp.wait_for_any_to_contain self.click_and_dont_wait_for_page_load = self.webapp.click_and_dont_wait_for_page_load # Configure selenium driver screen_res = self.settings.get( "screen_resolution", {"width": 1024, "height": 768, } ) self.driver.set_window_size( int(screen_res['width']), int(screen_res['height']) ) self.driver.set_window_position(0, 0) self.driver.implicitly_wait(2.0) self.driver.accept_next_alert = True chdir(PROJECT_DIRECTORY) def button_is_disabled(self, item): button = self.driver.find_element_by_id(item) # Using .is_enabled while disabled is true returns True as well, # so we'll check for it this way instead assert button.get_attribute('disabled') == 'true' def navigate_to(self, target): self.driver.get(target) def task_has_recent_progress_entries(self, task_id, expected_count): recent_progress = self.webapp.driver.find_elements_by_class_name( 'task_{task}_recent_progress'.format(task=task_id), ) assert len(recent_progress) == int(expected_count) def confirm_comment_today_is(self, expected): today = urllib.parse.quote_plus(datetime.datetime.strftime( datetime.datetime.today(), '%Y %b %d', )) element_id = '{date}_comment'.format(date=today) self.confirm_element_has_text( element_id=element_id, text=expected, ) def click_go_on_break_for_today(self): today = urllib.parse.quote_plus(datetime.datetime.strftime( datetime.datetime.today(), '%Y %b %d', )) break_id = 'go_on_break_{date}'.format(date=today) self.webapp.click(break_id) def test_on_break_task_input(self, section, area, goal_number, task_number): generators = { 'lower128': { 'all': self.generate_all_lower_128_unicode_string, }, 'high': { 'limit': self.generate_500_high_unicode_string, }, } comment = generators[section][area]() today = urllib.parse.quote_plus(datetime.datetime.strftime( datetime.datetime.today(), '%Y %b %d', )) self.webapp.click('task-%s_history' % task_number) self.webapp.click('go_on_break_%s' % today) self.fill_form( task_comment=comment, ) self.webapp.click('confirm-break') self.webapp.click('task-%s_history' % task_number) element = self.driver.find_elements_by_id('%s_on_break' % today)[0] comment_id = '{date}_comment'.format(date=today) comment_element = self.driver.find_elements_by_id(comment_id)[0] comment_text = html.unescape(comment_element.get_attribute('innerHTML')) comment_expected = html.unescape(comment) assert comment_text == comment_expected, '%s does not match comment %s' % (comment_text, comment_expected) self.webapp.click('home-link') def test_complete_task_input(self, section, area, goal_number, task_number): generators = { 'lower128': { 'all': self.generate_all_lower_128_unicode_string, }, 'high': { 'limit': self.generate_500_high_unicode_string, }, } comment = generators[section][area]() self.webapp.click('goal-%s-task-%s_incomplete' % ( goal_number, task_number, )) self.fill_form( task_comment=comment, ) self.webapp.click('complete-task') element = self.driver.find_elements_by_id('goal-%s-task-%s_complete' % (goal_number, task_number))[0] self.webapp.click('task-%s_history' % task_number) today = urllib.parse.quote_plus(datetime.datetime.strftime( datetime.datetime.today(), '%Y %b %d', )) comment_id = '{date}_comment'.format(date=today) comment_element = self.driver.find_elements_by_id(comment_id)[0] comment_text = html.unescape(comment_element.get_attribute('innerHTML')) comment_expected = html.unescape(comment) assert comment_text == comment_expected, '%s does not match comment %s' % (comment_text, comment_expected) self.webapp.click('home-link') def test_create_task_input(self, section, area, goal_number, task_number): generators = { 'lower128': { 'all': self.generate_all_lower_128_unicode_string, }, 'high': { 'limit': self.generate_200_high_unicode_string, }, } task_name = generators[section][area]() self.webapp.click('create-task') self.fill_form( task_name=task_name, associated_goal=str(goal_number), ) self.webapp.click('submit') element = self.driver.find_elements_by_id('goal-%s-task-%s_incomplete' % (goal_number, task_number))[0] element_text = html.unescape(element.get_attribute('innerHTML')) task_name = html.unescape(task_name) assert element_text == task_name, '%s does not match task %s' % (element_text, task_name) def test_create_goal_input(self, section, area, goal_number): generators = { 'lower128': { 'all': self.generate_all_lower_128_unicode_string, }, 'high': { 'limit': self.generate_200_high_unicode_string, }, } goal_name = generators[section][area]() self.webapp.click('create-goal') self.fill_form( goal_name=goal_name, parent_goal="None", ) self.webapp.click('submit') element = self.driver.find_elements_by_id('goal-%s' % goal_number)[0] element_text = html.unescape(element.get_attribute('innerHTML')) goal_name = html.unescape(goal_name) assert element_text == goal_name, '%s does not match goal %s' % (element_text, goal_name) def register_and_test_password_input(self, section, area): generators = { 'lower128': { 'all': self.generate_all_lower_128_unicode_string, }, 'high': { 'limit': self.generate_100_high_unicode_string, }, } username = '******'.format( section=section, area=area, ) email = '{user}@tester.local'.format(user=username) password = generators[section][area]() self.webapp.click('register-link') self.fill_form( username=username, password=password, password_confirm=password, email=email, email_confirm=email, ) self.webapp.click('register-button') self.webapp.click('logout') self.webapp.click('login') self.fill_form( username=username, password=password, ) self.webapp.click('login-button') self.wait_to_appear('my_user') self.webapp.click('logout') def register_and_test_login_input(self, section, area): generators = { 'lower128': { 'low': self.generate_first_50_lower_128_unicode_string, 'mid': self.generate_second_50_lower_128_unicode_string, 'high': self.generate_remaining_lower_128_unicode_string, 'all': self.generate_all_lower_128_unicode_string, }, 'high': { 'limit': self.generate_50_high_unicode_string, }, } username = generators[section][area]() email = 'inputtesterlogin{section}{area}@tester.local'.format( section=section, area=area, ) self.webapp.click('register-link') self.fill_form( username=username, password="******", password_confirm="inputtesterpassword", email=email, email_confirm=email, ) self.webapp.click('register-button') self.webapp.click('logout') self.webapp.click('login') self.fill_form( username=username, password='******', ) self.webapp.click('login-button') self.wait_to_appear('my_user') self.webapp.click('logout') def generate_all_lower_128_unicode_string(self): return ''.join([ chr(i) for i in range(32,128) ]) def generate_first_50_lower_128_unicode_string(self): return ''.join([ chr(i) for i in range(32,50) ]) def generate_second_50_lower_128_unicode_string(self): return ''.join([ chr(i) for i in range(50,100) ]) def generate_remaining_lower_128_unicode_string(self): return ''.join([ chr(i) for i in range(100,128) ]) def generate_500_high_unicode_string(self): return self.generate_big_unicode_string(length=500) def generate_200_high_unicode_string(self): return self.generate_big_unicode_string(length=200) def generate_100_high_unicode_string(self): return self.generate_big_unicode_string(length=100) def generate_50_high_unicode_string(self): return self.generate_big_unicode_string(length=50) def generate_big_unicode_string(self, length=50): # Uses largest UTF-8 character return ''.join([ chr(0x10FFFF) for i in range(length) ]) # TODO: Function to fill named field with lower 128 strings and strings of # arbitrary length def complete_task_yesterday(self): yesterday = urllib.parse.quote_plus(datetime.datetime.strftime( datetime.datetime.today() - datetime.timedelta(days=1), '%Y %b %d', )) complete_id = 'complete_{date}'.format(date=yesterday) self.webapp.click(complete_id) self.webapp.click('complete-task') def go_on_task_break_yesterday(self): yesterday = urllib.parse.quote_plus(datetime.datetime.strftime( datetime.datetime.today() - datetime.timedelta(days=1), '%Y %b %d', )) break_id = 'go_on_break_{date}'.format(date=yesterday) self.webapp.click(break_id) self.webapp.click('confirm-break') def navigate_to_break_for_today_by_id(self, base_url, task_id): today = urllib.parse.quote_plus(datetime.datetime.strftime( datetime.datetime.today(), '%Y %b %d', )) holiday_link = 'task_break/{task_id}/{today}'.format( task_id=task_id, today=today, ) target = urllib.parse.urljoin(base_url, holiday_link) self.navigate_to(target) def fail_when_clicking(self, item): """Fail if there is no failure when clicking an element""" self.webapp.click(item) try: self.driver.find_element_by_class_name("http-error") except NoSuchElementException: raise RuntimeError( "Clicking {} should not have succeeded".format(item) ) def fail_to_navigate_to(self, target): """Fail if there is no failure when navigating to a URL""" self.navigate_to(target) try: self.driver.find_element_by_class_name("http-error") except NoSuchElementException: raise RuntimeError( "Navigating to {} should not have succeeded".format(target) ) def set_task_creation_date_earlier(self, task_id, days_in_the_past): """Set a task to have been created earlier.""" creation = datetime.datetime.today() - datetime.timedelta( days=days_in_the_past, ) conn = sqlite3.connect(self.turkeydb_file) conn.execute( 'update tasks set creation_time=? where id=?', (creation, task_id) ) conn.commit() def _should_not_appear(self, item): """Only raise exception if element does appear.""" from selenium.common.exceptions import TimeoutException try: self.wait_to_appear(item) raise RuntimeError("Item {} appeared".format(item)) except TimeoutException: pass def historic_task_count_is(self, expected_count): """Check that the number of historic tasks on the page matches the expected amount.""" historic_tasks = self.webapp.driver.find_elements_by_class_name( 'historic-task' ) actual_count = len(historic_tasks) expected = int(expected_count) assert actual_count == expected, "Expected %s, saw %s" % ( expected, actual_count, ) def active_tasks_id_order_is(self, expected_order): """Get all task IDs by task_X_history buttons and check they're in the expected order.""" buttons = self.webapp.driver.find_elements_by_class_name('btn') task_history_buttons = [ button.get_attribute('id') for button in buttons if 'task' in button.get_attribute('id') and 'history' in button.get_attribute('id') ] task_order = [ int(task.split('_')[0].split('-')[1]) for task in task_history_buttons ] # Make sure the expected order uses integers to avoid difficult to # comprehend errors expected_order = [int(item) for item in expected_order] assert task_order == expected_order, 'Order was: %s. Expected: %s' % ( task_order, expected_order ) def confirm_element_has_text(self, element_id, text): element = self.webapp.driver.find_elements_by_id(element_id)[0] assert element.text == text def pause(self, message=None): """Pause test and launch IPython""" 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("http://localhost:5000") 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 wait_for_email(self, containing=None): """Wait for email.""" self.services['HitchSMTP'].logs.out.tail.until_json( lambda email: containing in email['payload'] or containing in email['subject'], timeout=45, lines_back=1, ) def confirm_emails_sent(self, number): """Count number of emails sent by app.""" assert len(self.services['HitchSMTP'].logs.json()) == int(number) # Can also specify minutes and hours... probably not useful yet? def time_travel(self, days=""): """Get in the Delorean, Marty!""" self.services.time_travel(days=int(days)) def connect_to_kernel(self, service_name): """Connect to IPython kernel embedded in service_name.""" self.services.connect_to_ipykernel(service_name) def on_failure(self): """Runs if there is a test failure""" if not self.settings['quiet']: if self.settings.get("pause_on_failure", False): self.pause(message=self.stacktrace.to_template()) def on_success(self): """Runs when a test successfully passes""" if self.settings.get("pause_on_success", False): self.pause(message="SUCCESS") def tear_down(self): """Run at the end of all tests.""" if hasattr(self, 'services'): self.services.shutdown() try: remove(self.turkey_conf_file) except FileNotFoundError: pass if not self.turkeydb_file_pre_existing: try: remove(self.turkeydb_file) except FileNotFoundError: pass
def set_up(self): """Set up your applications and the test environment.""" self.python_package = hitchpython.PythonPackage( python_version=self.settings['python_version'] ) self.python_package.build() self.python_package.verify() check_call([ self.python_package.pip, "install", "-r", path.join(PROJECT_DIRECTORY, "requirements.txt") ]) #postgres_package = hitchpostgres.PostgresPackage( #version=self.settings["postgres_version"], #) #postgres_package.build() turkeydb_filename = path.join(hitchtest.utils.get_hitch_directory(), "turkey.db") if path.exists(turkeydb_filename): remove(turkeydb_filename) with open(path.join(PROJECT_DIRECTORY, "turkey.conf"), "w") as turkey_conf: turkey_conf.write(json.dumps({ "SECRET_KEY": "xxx", "DEBUG": False, "SQLALCHEMY_TRACK_MODIFICATIONS": False, "SQLALCHEMY_DATABASE_URI": "sqlite:///{}".format(turkeydb_filename) })) chdir(PROJECT_DIRECTORY) check_call([self.python_package.python, "manage.py", "db", "upgrade"]) self.services = ServiceBundle( project_directory=PROJECT_DIRECTORY, startup_timeout=float(self.settings["startup_timeout"]), shutdown_timeout=float(self.settings["shutdown_timeout"]), ) # Docs : https://hitchtest.readthedocs.org/en/latest/plugins/hitchpostgres.html # Postgres user and database postgres_user = hitchpostgres.PostgresUser("example", "password") #self.services['Postgres'] = hitchpostgres.PostgresService( #postgres_package=postgres_package, #users=[postgres_user, ], #port=15432, #databases=[hitchpostgres.PostgresDatabase("example", postgres_user), ] #) # Docs : https://hitchtest.readthedocs.org/en/latest/plugins/hitchsmtp.html self.services['HitchSMTP'] = hitchsmtp.HitchSMTPService(port=10025) # Docs : https://hitchtest.readthedocs.org/en/latest/plugins/hitchpython.html self.services['Flask'] = hitchserve.Service( command=[self.python_package.python, "manage.py", "runserver", ], directory=PROJECT_DIRECTORY, needs=[], #[self.services['Postgres'], ], log_line_ready_checker=lambda line: "Running on" in line, ) # Docs : https://hitchtest.readthedocs.org/en/latest/plugins/hitchselenium.html self.services['Firefox'] = hitchselenium.SeleniumService( xvfb=self.settings.get("xvfb", False) or self.settings.get("quiet", False), no_libfaketime=True, ) self.services.startup(interactive=False) # Docs : https://hitchtest.readthedocs.org/en/latest/plugins/hitchselenium.html self.driver = self.services['Firefox'].driver self.webapp = hitchselenium.SeleniumStepLibrary( selenium_webdriver=self.driver, wait_for_timeout=5, ) self.click = self.webapp.click self.wait_to_appear = self.webapp.wait_to_appear self.wait_to_contain = self.webapp.wait_to_contain self.wait_for_any_to_contain = self.webapp.wait_for_any_to_contain self.click_and_dont_wait_for_page_load = self.webapp.click_and_dont_wait_for_page_load # Configure selenium driver screen_res = self.settings.get( "screen_resolution", {"width": 1024, "height": 768, } ) self.driver.set_window_size( int(screen_res['width']), int(screen_res['height']) ) self.driver.set_window_position(0, 0) self.driver.implicitly_wait(2.0) self.driver.accept_next_alert = True chdir(PROJECT_DIRECTORY)
class ExecutionEngine(hitchtest.ExecutionEngine): """Python engine for running tests.""" def set_up(self): """Set up your applications and the test environment.""" self.python_package = hitchpython.PythonPackage( python_version=self.settings['python_version'] ) self.python_package.build() self.python_package.verify() check_call([ self.python_package.pip, "install", "-r", path.join(PROJECT_DIRECTORY, "requirements.txt") ]) #postgres_package = hitchpostgres.PostgresPackage( #version=self.settings["postgres_version"], #) #postgres_package.build() turkeydb_filename = path.join(hitchtest.utils.get_hitch_directory(), "turkey.db") if path.exists(turkeydb_filename): remove(turkeydb_filename) with open(path.join(PROJECT_DIRECTORY, "turkey.conf"), "w") as turkey_conf: turkey_conf.write(json.dumps({ "SECRET_KEY": "xxx", "DEBUG": False, "SQLALCHEMY_TRACK_MODIFICATIONS": False, "SQLALCHEMY_DATABASE_URI": "sqlite:///{}".format(turkeydb_filename) })) chdir(PROJECT_DIRECTORY) check_call([self.python_package.python, "manage.py", "db", "upgrade"]) self.services = ServiceBundle( project_directory=PROJECT_DIRECTORY, startup_timeout=float(self.settings["startup_timeout"]), shutdown_timeout=float(self.settings["shutdown_timeout"]), ) # Docs : https://hitchtest.readthedocs.org/en/latest/plugins/hitchpostgres.html # Postgres user and database postgres_user = hitchpostgres.PostgresUser("example", "password") #self.services['Postgres'] = hitchpostgres.PostgresService( #postgres_package=postgres_package, #users=[postgres_user, ], #port=15432, #databases=[hitchpostgres.PostgresDatabase("example", postgres_user), ] #) # Docs : https://hitchtest.readthedocs.org/en/latest/plugins/hitchsmtp.html self.services['HitchSMTP'] = hitchsmtp.HitchSMTPService(port=10025) # Docs : https://hitchtest.readthedocs.org/en/latest/plugins/hitchpython.html self.services['Flask'] = hitchserve.Service( command=[self.python_package.python, "manage.py", "runserver", ], directory=PROJECT_DIRECTORY, needs=[], #[self.services['Postgres'], ], log_line_ready_checker=lambda line: "Running on" in line, ) # Docs : https://hitchtest.readthedocs.org/en/latest/plugins/hitchselenium.html self.services['Firefox'] = hitchselenium.SeleniumService( xvfb=self.settings.get("xvfb", False) or self.settings.get("quiet", False), no_libfaketime=True, ) self.services.startup(interactive=False) # Docs : https://hitchtest.readthedocs.org/en/latest/plugins/hitchselenium.html self.driver = self.services['Firefox'].driver self.webapp = hitchselenium.SeleniumStepLibrary( selenium_webdriver=self.driver, wait_for_timeout=5, ) self.click = self.webapp.click self.wait_to_appear = self.webapp.wait_to_appear self.wait_to_contain = self.webapp.wait_to_contain self.wait_for_any_to_contain = self.webapp.wait_for_any_to_contain self.click_and_dont_wait_for_page_load = self.webapp.click_and_dont_wait_for_page_load # Configure selenium driver screen_res = self.settings.get( "screen_resolution", {"width": 1024, "height": 768, } ) self.driver.set_window_size( int(screen_res['width']), int(screen_res['height']) ) self.driver.set_window_position(0, 0) self.driver.implicitly_wait(2.0) self.driver.accept_next_alert = True chdir(PROJECT_DIRECTORY) def pause(self, message=None): """Pause test and launch IPython""" 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("http://localhost:5000") 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 wait_for_email(self, containing=None): """Wait for email.""" self.services['HitchSMTP'].logs.out.tail.until_json( lambda email: containing in email['payload'] or containing in email['subject'], timeout=45, lines_back=1, ) def confirm_emails_sent(self, number): """Count number of emails sent by app.""" assert len(self.services['HitchSMTP'].logs.json()) == int(number) def time_travel(self, days=""): """Get in the Delorean, Marty!""" self.services.time_travel(days=int(days)) def connect_to_kernel(self, service_name): """Connect to IPython kernel embedded in service_name.""" self.services.connect_to_ipykernel(service_name) def on_failure(self): """Runs if there is a test failure""" if not self.settings['quiet']: if self.settings.get("pause_on_failure", False): self.pause(message=self.stacktrace.to_template()) def on_success(self): """Runs when a test successfully passes""" if self.settings.get("pause_on_success", False): self.pause(message="SUCCESS") def tear_down(self): """Run at the end of all tests.""" if hasattr(self, 'services'): self.services.shutdown()
def set_up(self): """Set up your applications and the test environment.""" self.path.project = self.path.engine.parent self.path.config_file = self.path.project.joinpath("config.py") self.path.appdb = self.path.project.joinpath("app.db") self.path.testdb = self.path.project.joinpath("test.db") if self.path.appdb.exists(): self.path.appdb.remove() if self.path.testdb.exists(): self.path.testdb.remove() self.path.config_file.write_text(( """import os\n""" """basedir = os.path.abspath(os.path.dirname(__file__))\n""" """\n""" """SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(basedir, 'app.db')\n""" """SQLALCHEMY_MIGRATE_REPO = os.path.join(basedir, 'db_repository')\n""" """WTF_CSRF_ENABLED = True\n""" """SECRET_KEY = 'you-will-never-guess'\n""" )) self.python_package = hitchpython.PythonPackage( python_version=self.settings['python_version'] ) self.python_package.build() self.python = self.python_package.cmd.python.in_dir(self.path.project) self.pip = self.python_package.cmd.pip.in_dir(self.path.project) with monitor([self.path.project.joinpath("requirements.txt"), ]) as changed: if changed: run(self.pip("install", "-r", "requirements.txt")) run(Command("bash")("-c", "sqlite3 {0}/test.db < {0}/test.sql".format(self.path.project))) #run(self.python("db_create.py")) #run(self.python("db_migrate.py")) self.services = ServiceBundle( project_directory=str(self.path.project), startup_timeout=float(self.settings["startup_timeout"]), shutdown_timeout=float(self.settings["shutdown_timeout"]), ) # Docs : https://hitchtest.readthedocs.org/en/latest/plugins/hitchpython.html self.services['Flask'] = hitchserve.Service( command=self.python("run.py"), log_line_ready_checker=lambda line: "Restarting with stat" in line, ) # Docs : https://hitchtest.readthedocs.org/en/latest/plugins/hitchselenium.html self.services['Firefox'] = hitchselenium.SeleniumService( xvfb=self.settings.get("xvfb", False) or self.settings.get("quiet", False), no_libfaketime=True, ) self.services.startup(interactive=False) # Docs : https://hitchtest.readthedocs.org/en/latest/plugins/hitchselenium.html self.driver = self.services['Firefox'].driver self.webapp = hitchselenium.SeleniumStepLibrary( selenium_webdriver=self.driver, wait_for_timeout=5, ) self.click = self.webapp.click self.wait_to_appear = self.webapp.wait_to_appear self.wait_to_contain = self.webapp.wait_to_contain self.wait_for_any_to_contain = self.webapp.wait_for_any_to_contain self.click_and_dont_wait_for_page_load = self.webapp.click_and_dont_wait_for_page_load # Configure selenium driver screen_res = self.settings.get( "screen_resolution", {"width": 1024, "height": 768, } ) self.driver.set_window_size( int(screen_res['width']), int(screen_res['height']) ) self.driver.set_window_position(0, 0) self.driver.implicitly_wait(2.0) self.driver.accept_next_alert = True
class ExecutionEngine(hitchtest.ExecutionEngine): """Python engine for running tests on chess app.""" def set_up(self): """Set up your applications and the test environment.""" self.path.project = self.path.engine.parent self.path.config_file = self.path.project.joinpath("config.py") self.path.appdb = self.path.project.joinpath("app.db") self.path.testdb = self.path.project.joinpath("test.db") if self.path.appdb.exists(): self.path.appdb.remove() if self.path.testdb.exists(): self.path.testdb.remove() self.path.config_file.write_text(( """import os\n""" """basedir = os.path.abspath(os.path.dirname(__file__))\n""" """\n""" """SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(basedir, 'app.db')\n""" """SQLALCHEMY_MIGRATE_REPO = os.path.join(basedir, 'db_repository')\n""" """WTF_CSRF_ENABLED = True\n""" """SECRET_KEY = 'you-will-never-guess'\n""" )) self.python_package = hitchpython.PythonPackage( python_version=self.settings['python_version'] ) self.python_package.build() self.python = self.python_package.cmd.python.in_dir(self.path.project) self.pip = self.python_package.cmd.pip.in_dir(self.path.project) with monitor([self.path.project.joinpath("requirements.txt"), ]) as changed: if changed: run(self.pip("install", "-r", "requirements.txt")) run(Command("bash")("-c", "sqlite3 {0}/test.db < {0}/test.sql".format(self.path.project))) #run(self.python("db_create.py")) #run(self.python("db_migrate.py")) self.services = ServiceBundle( project_directory=str(self.path.project), startup_timeout=float(self.settings["startup_timeout"]), shutdown_timeout=float(self.settings["shutdown_timeout"]), ) # Docs : https://hitchtest.readthedocs.org/en/latest/plugins/hitchpython.html self.services['Flask'] = hitchserve.Service( command=self.python("run.py"), log_line_ready_checker=lambda line: "Restarting with stat" in line, ) # Docs : https://hitchtest.readthedocs.org/en/latest/plugins/hitchselenium.html self.services['Firefox'] = hitchselenium.SeleniumService( xvfb=self.settings.get("xvfb", False) or self.settings.get("quiet", False), no_libfaketime=True, ) self.services.startup(interactive=False) # Docs : https://hitchtest.readthedocs.org/en/latest/plugins/hitchselenium.html self.driver = self.services['Firefox'].driver self.webapp = hitchselenium.SeleniumStepLibrary( selenium_webdriver=self.driver, wait_for_timeout=5, ) self.click = self.webapp.click self.wait_to_appear = self.webapp.wait_to_appear self.wait_to_contain = self.webapp.wait_to_contain self.wait_for_any_to_contain = self.webapp.wait_for_any_to_contain self.click_and_dont_wait_for_page_load = self.webapp.click_and_dont_wait_for_page_load # Configure selenium driver screen_res = self.settings.get( "screen_resolution", {"width": 1024, "height": 768, } ) self.driver.set_window_size( int(screen_res['width']), int(screen_res['height']) ) self.driver.set_window_position(0, 0) self.driver.implicitly_wait(2.0) self.driver.accept_next_alert = True def pause(self, message=None): """Pause test and launch IPython""" 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("http://localhost:5000") def time_travel(self, days=""): """Get in the Delorean, Marty!""" self.services.time_travel(days=int(days)) def connect_to_kernel(self, service_name): """Connect to IPython kernel embedded in service_name.""" self.services.connect_to_ipykernel(service_name) def on_failure(self): """Runs if there is a test failure""" if self.settings.get("kaching", False): kaching.fail() if not self.settings['quiet']: if self.settings.get("pause_on_failure", False): self.pause(message=self.stacktrace.to_template()) def on_success(self): """Runs when a test successfully passes""" if self.settings.get("kaching", False): kaching.win() if self.settings.get("pause_on_success", False): self.pause(message="SUCCESS") def tear_down(self): """Run at the end of all tests.""" if hasattr(self, 'services'): self.services.shutdown()
class ExecutionEngine(hitchtest.ExecutionEngine): """Engine for orchestating and interacting with the TODO app.""" def set_up(self): """Ensure python environment present, then run all services.""" python_package = hitchpython.PythonPackage( python_version=self.settings['python_version'], directory=path.join( PROJECT_DIRECTORY, "pyv{}".format( self.settings['python_version'] ) ) ) python_package.build() python_package.verify() call([ python_package.pip, "install", "-r", path.join(PROJECT_DIRECTORY, "requirements.txt") ]) postgres_package = hitchpostgres.PostgresPackage( version=self.settings["postgres_version"], ) postgres_package.build() postgres_package.verify() self.services = ServiceBundle( project_directory=PROJECT_DIRECTORY, startup_timeout=float(self.settings["startup_timeout"]), shutdown_timeout=5.0, ) postgres_user = hitchpostgres.PostgresUser("patrycja", "mypassword") self.services['Postgres'] = hitchpostgres.PostgresService( port=5432, postgres_package=postgres_package, users=[postgres_user, ], databases=[hitchpostgres.PostgresDatabase("todoapp", postgres_user), ] ) self.services['Flask'] = FlaskService( python=python_package.python, needs=[self.services['Postgres'],] ) self.services['Firefox'] = hitchselenium.SeleniumService( xvfb=self.settings.get("xvfb", False) or self.settings.get("quiet", False), no_libfaketime=True, ) self.services.startup(interactive=False) # Configure selenium driver self.driver = self.services['Firefox'].driver self.driver.set_window_size(800, 600) 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.""" time.sleep(0.5) # Turns out that flask isn't entirely truthful about when it is running self.driver.get("http://localhost:5000") 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 time_travel(self, days=""): """Move services forward in time x days""" self.services.time_travel(days=int(days)) def on_success(self): pass def on_failure(self): pass def tear_down(self): """Shut down all of the services.""" if hasattr(self, 'services'): self.services.shutdown()
def set_up(self): """Ensure virtualenv present, then run all services.""" chdir(PROJECT_DIRECTORY) python_package = hitchpython.PythonPackage( python_version=self.preconditions['python_version'] ) python_package.build() check_call([ python_package.pip, "install", "-r", path.join(PROJECT_DIRECTORY, "requirements.txt") ]) postgres_package = hitchpostgres.PostgresPackage( version=self.settings["postgres_version"], ) postgres_package.build() redis_package = hitchredis.RedisPackage( version=self.settings.get("redis_version") ) redis_package.build() node_package = hitchnode.NodePackage() node_package.build() if not path.exists(path.join( hitchtest.utils.get_hitch_directory(), "node_modules", "less", "bin", "lessc" )): chdir(hitchtest.utils.get_hitch_directory()) check_call([node_package.npm, "install", "less"]) chdir(PROJECT_DIRECTORY) self.services = ServiceBundle( project_directory=PROJECT_DIRECTORY, startup_timeout=float(self.settings["startup_timeout"]), shutdown_timeout=5.0, ) # Postgres user called remindme with password 'password' required - see Django's settings.py postgres_user = hitchpostgres.PostgresUser("remindme", "password") self.services['Postgres'] = hitchpostgres.PostgresService( postgres_package=postgres_package, users=[postgres_user, ], databases=[hitchpostgres.PostgresDatabase("remindme", postgres_user), ] ) self.services['HitchSMTP'] = hitchsmtp.HitchSMTPService() self.services['Redis'] = hitchredis.RedisService( redis_package=redis_package, port=16379, ) dj_env_vars = copy.copy(os.environ) dj_env_vars['PATH'] = "{}:{}:{}".format( dj_env_vars['PATH'], node_package.bin_directory, path.join(hitchtest.utils.get_hitch_directory(), "node_modules", "less", "bin") ) self.services['Django'] = hitchpython.DjangoService( python=python_package.python, settings="remindme.settings", needs=[self.services['Postgres'], ], env_vars=dj_env_vars ) self.services['Celery'] = hitchpython.CeleryService( python=python_package.python, app="remindme", loglevel="INFO", needs=[ self.services['Redis'], self.services['Postgres'], ] ) self.services['Firefox'] = hitchselenium.SeleniumService( xvfb=self.settings.get("xvfb", False) or self.settings.get("quiet", False), no_libfaketime=True, ) self.services['Cron'] = hitchcron.CronService( run=self.services['Django'].manage("trigger").command, every=1, needs=[ self.services['Django'], self.services['Celery'], ], ) self.services.startup(interactive=False) # Configure selenium driver self.driver = self.services['Firefox'].driver #self.driver.set_window_size(450, 350) #self.driver.set_window_position(0, 0) self.driver.implicitly_wait(2.0) self.driver.accept_next_alert = True
class ExecutionEngine(hitchtest.ExecutionEngine): """Engine for orchestating and interacting with the reminders app.""" def set_up(self): """Ensure virtualenv present, then run all services.""" chdir(PROJECT_DIRECTORY) python_package = hitchpython.PythonPackage( python_version=self.preconditions['python_version'] ) python_package.build() check_call([ python_package.pip, "install", "-r", path.join(PROJECT_DIRECTORY, "requirements.txt") ]) postgres_package = hitchpostgres.PostgresPackage( version=self.settings["postgres_version"], ) postgres_package.build() redis_package = hitchredis.RedisPackage( version=self.settings.get("redis_version") ) redis_package.build() node_package = hitchnode.NodePackage() node_package.build() if not path.exists(path.join( hitchtest.utils.get_hitch_directory(), "node_modules", "less", "bin", "lessc" )): chdir(hitchtest.utils.get_hitch_directory()) check_call([node_package.npm, "install", "less"]) chdir(PROJECT_DIRECTORY) self.services = ServiceBundle( project_directory=PROJECT_DIRECTORY, startup_timeout=float(self.settings["startup_timeout"]), shutdown_timeout=5.0, ) # Postgres user called remindme with password 'password' required - see Django's settings.py postgres_user = hitchpostgres.PostgresUser("remindme", "password") self.services['Postgres'] = hitchpostgres.PostgresService( postgres_package=postgres_package, users=[postgres_user, ], databases=[hitchpostgres.PostgresDatabase("remindme", postgres_user), ] ) self.services['HitchSMTP'] = hitchsmtp.HitchSMTPService() self.services['Redis'] = hitchredis.RedisService( redis_package=redis_package, port=16379, ) dj_env_vars = copy.copy(os.environ) dj_env_vars['PATH'] = "{}:{}:{}".format( dj_env_vars['PATH'], node_package.bin_directory, path.join(hitchtest.utils.get_hitch_directory(), "node_modules", "less", "bin") ) self.services['Django'] = hitchpython.DjangoService( python=python_package.python, settings="remindme.settings", needs=[self.services['Postgres'], ], env_vars=dj_env_vars ) self.services['Celery'] = hitchpython.CeleryService( python=python_package.python, app="remindme", loglevel="INFO", needs=[ self.services['Redis'], self.services['Postgres'], ] ) self.services['Firefox'] = hitchselenium.SeleniumService( xvfb=self.settings.get("xvfb", False) or self.settings.get("quiet", False), no_libfaketime=True, ) self.services['Cron'] = hitchcron.CronService( run=self.services['Django'].manage("trigger").command, every=1, needs=[ self.services['Django'], self.services['Celery'], ], ) self.services.startup(interactive=False) # Configure selenium driver self.driver = self.services['Firefox'].driver #self.driver.set_window_size(450, 350) #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.execute_script("document.getElementById('{}').click();".format(on)) 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=45, lines_back=1, ) def time_travel(self, days=""): """Get in the Delorean, Marty!""" self.services.time_travel(days=int(days)) def connect_to_kernel(self, service_name): self.services.connect_to_ipykernel(service_name) def on_failure(self): """Stop and IPython.""" if call(["which", "kaching"], stdout=PIPE) == 0: call(["kaching", "fail"]) # sudo pip install kaching for sad sound if self.settings.get("pause_on_failure", False): self.pause(message=self.stacktrace.to_template()) def on_success(self): """Ka-ching!""" if call(["which", "kaching"], stdout=PIPE) == 0: call(["kaching", "pass"]) # sudo pip install kaching for happy sound if self.settings.get("pause_on_success", False): self.pause(message="SUCCESS") def tear_down(self): """Commit genocide on the services required to run your test.""" if hasattr(self, 'services'): self.services.shutdown()
def set_up(self): """Ensure virtualenv present, then run all services.""" python_package = hitchpython.PythonPackage( python_version=self.preconditions['python_version'], directory=path.join( PROJECT_DIRECTORY, "pyv{}".format( self.preconditions['python_version'] ) ) ) python_package.build() python_package.verify() call([ python_package.pip, "install", "-r", path.join(PROJECT_DIRECTORY, "requirements.txt") ]) postgres_package = hitchpostgres.PostgresPackage( version=self.settings["postgres_version"], ) postgres_package.build() postgres_package.verify() redis_package = hitchredis.RedisPackage( version=self.settings.get("redis_version") ) redis_package.build() redis_package.verify() self.services = ServiceBundle( project_directory=PROJECT_DIRECTORY, startup_timeout=float(self.settings["startup_timeout"]), shutdown_timeout=5.0, ) # Postgres user called remindme with password 'password' required - see Django's settings.py postgres_user = hitchpostgres.PostgresUser("remindme", "password") self.services['Postgres'] = hitchpostgres.PostgresService( postgres_package=postgres_package, users=[postgres_user, ], databases=[hitchpostgres.PostgresDatabase("remindme", postgres_user), ] ) self.services['HitchSMTP'] = hitchsmtp.HitchSMTPService() self.services['Redis'] = hitchredis.RedisService( redis_package=redis_package, port=16379, ) self.services['Django'] = hitchpython.DjangoService( python=python_package.python, version=str(self.settings.get("django_version")), settings="remindme.settings", needs=[self.services['Postgres'], ] ) self.services['Celery'] = hitchpython.CeleryService( python=python_package.python, version=self.settings.get("celery_version"), app="remindme", loglevel="INFO", needs=[ self.services['Redis'], self.services['Postgres'], ] ) self.services['Firefox'] = hitchselenium.SeleniumService( xvfb=self.settings.get("xvfb", False) or self.settings.get("quiet", False), no_libfaketime=True, ) self.services['Cron'] = hitchcron.CronService( run=self.services['Django'].manage("trigger").command, every=1, needs=[ self.services['Django'], self.services['Celery'], ], ) self.services.startup(interactive=False) # Configure selenium driver self.driver = self.services['Firefox'].driver self.driver.set_window_size(450, 350) self.driver.set_window_position(0, 0) self.driver.implicitly_wait(2.0) self.driver.accept_next_alert = True
def set_up(self): """Set up your applications and the test environment.""" self.python_package = hitchpython.PythonPackage( python_version=self.settings['python_version']) self.python_package.build() self.python_package.verify() check_call([ self.python_package.pip, "install", "-r", path.join(PROJECT_DIRECTORY, "requirements.txt") ]) #postgres_package = hitchpostgres.PostgresPackage( #version=self.settings["postgres_version"], #) #postgres_package.build() turkeydb_filename = path.join(hitchtest.utils.get_hitch_directory(), "turkey.db") if path.exists(turkeydb_filename): remove(turkeydb_filename) with open(path.join(PROJECT_DIRECTORY, "turkey.conf"), "w") as turkey_conf: turkey_conf.write( json.dumps({ "SECRET_KEY": "xxx", "DEBUG": False, "SQLALCHEMY_TRACK_MODIFICATIONS": False, "SQLALCHEMY_DATABASE_URI": "sqlite:///{}".format(turkeydb_filename) })) chdir(PROJECT_DIRECTORY) check_call([self.python_package.python, "manage.py", "db", "upgrade"]) self.services = ServiceBundle( project_directory=PROJECT_DIRECTORY, startup_timeout=float(self.settings["startup_timeout"]), shutdown_timeout=float(self.settings["shutdown_timeout"]), ) # Docs : https://hitchtest.readthedocs.org/en/latest/plugins/hitchpostgres.html # Postgres user and database postgres_user = hitchpostgres.PostgresUser("example", "password") #self.services['Postgres'] = hitchpostgres.PostgresService( #postgres_package=postgres_package, #users=[postgres_user, ], #port=15432, #databases=[hitchpostgres.PostgresDatabase("example", postgres_user), ] #) # Docs : https://hitchtest.readthedocs.org/en/latest/plugins/hitchsmtp.html self.services['HitchSMTP'] = hitchsmtp.HitchSMTPService(port=10025) # Docs : https://hitchtest.readthedocs.org/en/latest/plugins/hitchpython.html self.services['Flask'] = hitchserve.Service( command=[ self.python_package.python, "manage.py", "runserver", ], directory=PROJECT_DIRECTORY, needs=[], #[self.services['Postgres'], ], log_line_ready_checker=lambda line: "Running on" in line, ) # Docs : https://hitchtest.readthedocs.org/en/latest/plugins/hitchselenium.html self.services['Firefox'] = hitchselenium.SeleniumService( xvfb=self.settings.get("xvfb", False) or self.settings.get("quiet", False), no_libfaketime=True, ) self.services.startup(interactive=False) # Docs : https://hitchtest.readthedocs.org/en/latest/plugins/hitchselenium.html self.driver = self.services['Firefox'].driver self.webapp = hitchselenium.SeleniumStepLibrary( selenium_webdriver=self.driver, wait_for_timeout=5, ) self.click = self.webapp.click self.wait_to_appear = self.webapp.wait_to_appear self.wait_to_contain = self.webapp.wait_to_contain self.wait_for_any_to_contain = self.webapp.wait_for_any_to_contain self.click_and_dont_wait_for_page_load = self.webapp.click_and_dont_wait_for_page_load # Configure selenium driver screen_res = self.settings.get("screen_resolution", { "width": 1024, "height": 768, }) self.driver.set_window_size(int(screen_res['width']), int(screen_res['height'])) self.driver.set_window_position(0, 0) self.driver.implicitly_wait(2.0) self.driver.accept_next_alert = True chdir(PROJECT_DIRECTORY)
class ExecutionEngine(hitchtest.ExecutionEngine): """Python engine for running tests.""" def set_up(self): """Set up your applications and the test environment.""" self.python_package = hitchpython.PythonPackage( python_version=self.settings['python_version']) self.python_package.build() self.python_package.verify() check_call([ self.python_package.pip, "install", "-r", path.join(PROJECT_DIRECTORY, "requirements.txt") ]) #postgres_package = hitchpostgres.PostgresPackage( #version=self.settings["postgres_version"], #) #postgres_package.build() turkeydb_filename = path.join(hitchtest.utils.get_hitch_directory(), "turkey.db") if path.exists(turkeydb_filename): remove(turkeydb_filename) with open(path.join(PROJECT_DIRECTORY, "turkey.conf"), "w") as turkey_conf: turkey_conf.write( json.dumps({ "SECRET_KEY": "xxx", "DEBUG": False, "SQLALCHEMY_TRACK_MODIFICATIONS": False, "SQLALCHEMY_DATABASE_URI": "sqlite:///{}".format(turkeydb_filename) })) chdir(PROJECT_DIRECTORY) check_call([self.python_package.python, "manage.py", "db", "upgrade"]) self.services = ServiceBundle( project_directory=PROJECT_DIRECTORY, startup_timeout=float(self.settings["startup_timeout"]), shutdown_timeout=float(self.settings["shutdown_timeout"]), ) # Docs : https://hitchtest.readthedocs.org/en/latest/plugins/hitchpostgres.html # Postgres user and database postgres_user = hitchpostgres.PostgresUser("example", "password") #self.services['Postgres'] = hitchpostgres.PostgresService( #postgres_package=postgres_package, #users=[postgres_user, ], #port=15432, #databases=[hitchpostgres.PostgresDatabase("example", postgres_user), ] #) # Docs : https://hitchtest.readthedocs.org/en/latest/plugins/hitchsmtp.html self.services['HitchSMTP'] = hitchsmtp.HitchSMTPService(port=10025) # Docs : https://hitchtest.readthedocs.org/en/latest/plugins/hitchpython.html self.services['Flask'] = hitchserve.Service( command=[ self.python_package.python, "manage.py", "runserver", ], directory=PROJECT_DIRECTORY, needs=[], #[self.services['Postgres'], ], log_line_ready_checker=lambda line: "Running on" in line, ) # Docs : https://hitchtest.readthedocs.org/en/latest/plugins/hitchselenium.html self.services['Firefox'] = hitchselenium.SeleniumService( xvfb=self.settings.get("xvfb", False) or self.settings.get("quiet", False), no_libfaketime=True, ) self.services.startup(interactive=False) # Docs : https://hitchtest.readthedocs.org/en/latest/plugins/hitchselenium.html self.driver = self.services['Firefox'].driver self.webapp = hitchselenium.SeleniumStepLibrary( selenium_webdriver=self.driver, wait_for_timeout=5, ) self.click = self.webapp.click self.wait_to_appear = self.webapp.wait_to_appear self.wait_to_contain = self.webapp.wait_to_contain self.wait_for_any_to_contain = self.webapp.wait_for_any_to_contain self.click_and_dont_wait_for_page_load = self.webapp.click_and_dont_wait_for_page_load # Configure selenium driver screen_res = self.settings.get("screen_resolution", { "width": 1024, "height": 768, }) self.driver.set_window_size(int(screen_res['width']), int(screen_res['height'])) self.driver.set_window_position(0, 0) self.driver.implicitly_wait(2.0) self.driver.accept_next_alert = True chdir(PROJECT_DIRECTORY) def pause(self, message=None): """Pause test and launch IPython""" 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("http://localhost:5000") 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 wait_for_email(self, containing=None): """Wait for email.""" self.services['HitchSMTP'].logs.out.tail.until_json( lambda email: containing in email['payload'] or containing in email['subject'], timeout=45, lines_back=1, ) def confirm_emails_sent(self, number): """Count number of emails sent by app.""" assert len(self.services['HitchSMTP'].logs.json()) == int(number) def time_travel(self, days=""): """Get in the Delorean, Marty!""" self.services.time_travel(days=int(days)) def connect_to_kernel(self, service_name): """Connect to IPython kernel embedded in service_name.""" self.services.connect_to_ipykernel(service_name) def on_failure(self): """Runs if there is a test failure""" if not self.settings['quiet']: if self.settings.get("pause_on_failure", False): self.pause(message=self.stacktrace.to_template()) def on_success(self): """Runs when a test successfully passes""" if self.settings.get("pause_on_success", False): self.pause(message="SUCCESS") def tear_down(self): """Run at the end of all tests.""" if hasattr(self, 'services'): self.services.shutdown()