Exemple #1
0
    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()
Exemple #4
0
    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)
Exemple #5
0
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
Exemple #6
0
    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)
Exemple #7
0
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()
Exemple #8
0
    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
Exemple #9
0
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()
Exemple #10
0
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
Exemple #14
0
    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)
Exemple #15
0
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()