Source code for fobi.tests.test_browser_build_dynamic_forms

import gc
import logging
import unittest

from time import sleep

# from selenium.webdriver.firefox.webdriver import WebDriver
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.common.exceptions import WebDriverException

from django.core.management import call_command
from django.core.urlresolvers import reverse
from django.test import LiveServerTestCase
from django.conf import settings

from fobi.models import FormEntry

from fobi.tests.base import print_info, skip  # , BaseBrowserTest
from fobi.tests.helpers import (
    setup_fobi, get_or_create_admin_user, db_clean_up
)
from fobi.tests import constants
from fobi.tests.data import (
    TEST_FORM_ELEMENT_PLUGIN_DATA, TEST_FORM_FIELD_DATA,
    TEST_FORM_HANDLER_PLUGIN_DATA
)

__title__ = 'fobi.tests.test_browser_build_dynamic_forms'
__author__ = 'Artur Barseghyan <artur.barseghyan@gmail.com>'
__copyright__ = '2014-2016 Artur Barseghyan'
__license__ = 'GPL 2.0/LGPL 2.1'
__all__ = ('FobiBrowserBuldDynamicFormsTest',)

logger = logging.getLogger(__name__)

TIMEOUT = 4
WAIT = False
WAIT_FOR = 0


[docs]class FobiBrowserBuldDynamicFormsTest(LiveServerTestCase): """Browser tests django-fobi bulding forms functionality. Backed up by selenium. This test is based on the bootstrap3 theme. """ cleans_up_after_itself = True try: LIVE_SERVER_URL = settings.LIVE_SERVER_URL except Exception as e: LIVE_SERVER_URL = None
[docs] def tearDown(self): """Tear down.""" super(FobiBrowserBuldDynamicFormsTest, self).tearDown() call_command('flush', verbosity=0, interactive=False, reset_sequences=False, allow_cascade=False, inhibit_post_migrate=False) gc.collect()
@classmethod
[docs] def setUpClass(cls): """Set up class.""" # cls.selenium = WebDriver() cls.selenium = webdriver.Firefox() setup_fobi(fobi_sync_plugins=True) # user = get_or_create_admin_user() # create_form_with_entries(user) super(FobiBrowserBuldDynamicFormsTest, cls).setUpClass()
@classmethod
[docs] def tearDownClass(cls): """Tear down class.""" try: cls.selenium.quit() except Exception as err: print(err) super(FobiBrowserBuldDynamicFormsTest, cls).tearDownClass() call_command('flush', verbosity=0, interactive=False, reset_sequences=False, allow_cascade=False, inhibit_post_migrate=False) gc.collect()
# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # +++++++++++++++++++++++++ Internals +++++++++++++++++++++++++++ # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # +++++++++++++++++++++++++++ General +++++++++++++++++++++++++++ # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ def __get_live_server_url(self): """Get live server URL.""" return self.LIVE_SERVER_URL if self.LIVE_SERVER_URL \ else self.live_server_url def __authenticate(self): """Authenticate.""" # Make sure the user exists user = get_or_create_admin_user() self.selenium.get( '{0}{1}'.format( self.__get_live_server_url(), reverse('auth_login') ) ) self.selenium.maximize_window() username_input = self.selenium.find_element_by_name("username") username_input.send_keys(constants.FOBI_TEST_USER_USERNAME) password_input = self.selenium.find_element_by_name("password") password_input.send_keys(constants.FOBI_TEST_USER_PASSWORD) self.selenium.find_element_by_xpath('//button[@type="submit"]').click() # Wait until the list view opens WebDriverWait(self.selenium, timeout=TIMEOUT).until( # lambda driver: driver.find_element_by_id('id_main') lambda driver: driver.find_element_by_xpath( '//body[contains(@class, "theme")]' ) ) def __sleep(self, wait=WAIT_FOR): """Sleep.""" if WAIT and wait: self.selenium.implicitly_wait(wait) def __go_to_dashboard(self, wait=WAIT_FOR): """Go to dashboard.""" # Authenticate user. self.__authenticate() # Open the dashboard. url = reverse('fobi.dashboard') self.selenium.get('{0}{1}'.format(self.__get_live_server_url(), url)) # Wait until the edit widget form opens WebDriverWait(self.selenium, timeout=TIMEOUT).until( lambda driver: driver.find_element_by_xpath( '//body[contains(@class, "theme-bootstrap3")]' ) ) self.__sleep(wait) def _scroll_to_element(self, form_element, simple=False): """Scroll to element.""" coordinates = form_element.location_once_scrolled_into_view if simple: return x = coordinates.get('x', 0) y = coordinates.get('y', 0) self.selenium.execute_script( "window.scrollTo({0}, {1});".format(x, y) ) self.selenium.execute_script( "window.scrollBy({0}, {1});".format(0, -100) ) def _scroll_to(self, x, y): """Scroll to.""" self.selenium.execute_script( "window.scrollTo({0}, {1});".format(x, y) ) def _scroll_by(self, x, y): """Scroll by.""" self.selenium.execute_script( "window.scrollBy({0}, {1});".format(x, y) ) # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # ++++++++++++++++++++++ Form related +++++++++++++++++++++++++++ # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ def __test_add_form(self, wait=WAIT_FOR): """Test add form.""" # First open the dashboard self.__go_to_dashboard() # Follow the create form link. # Click the button to go to dashboard edit self.selenium.find_element_by_xpath( '//a[contains(@class, "list-group-item")]' ).click() # Wait until the dashboard edit view opens WebDriverWait(self.selenium, timeout=TIMEOUT).until( # lambda driver: driver.find_element_by_id('id_main') lambda driver: driver.find_element_by_xpath( '//body[contains(@class, "theme-bootstrap3")]' ) ) form_data = { 'name': constants.TEST_FORM_NAME, # 'user': get_or_create_admin_user(), # 'slug': constants.TEST_FORM_SLUG, 'is_public': True, 'success_page_title': "Success page title", 'success_page_message': "Success page message", } if form_data: for field_name, field_value in form_data.items(): field_input = self.selenium.find_element_by_name(field_name) field_input.send_keys(field_value) # Click add widget button self.selenium.find_element_by_xpath('//button[@type="submit"]').click() logger.debug( """//div[contains(text(), 'Form {0} was created successfully.') and contains(@class, "alert-info")]""".format( constants.TEST_FORM_NAME ) ) # Wait until the fobi page opens with the form element in WebDriverWait(self.selenium, timeout=TIMEOUT).until( lambda driver: driver.find_element_by_xpath( """//div[contains(text(), 'Form {0} was created successfully.') and contains(@class, "alert-info")]""".format( constants.TEST_FORM_NAME ) ) ) self.__sleep(wait) def __get_form(self): """Get form object.""" return FormEntry._default_manager.get(name=constants.TEST_FORM_NAME) # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # ++++++++++++++++++++ Form element specific ++++++++++++++++++++ # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ def __add_form_element(self, form_element_name, form_element_data, wait=WAIT_FOR): """Add a single plugin to the form. At this stage we should be in the edit form entry interface. """ # Click the add form element button to add a new form element to the # form. add_form_element_link = self.selenium.find_element_by_xpath( """//a[contains(text(), 'Choose form element to add') and contains(@class, "dropdown-toggle")]""" ) self._scroll_to(0, 0) add_form_element_link.click() # Find the parent element add_form_element_parent_container = \ add_form_element_link.find_element_by_xpath('..') # Find the container of the available form elements add_form_element_available_elements_container = \ add_form_element_parent_container.find_element_by_xpath( '//ul[contains(@class, "dropdown-menu")]' ) # Click on the element we want form_element_to_add = \ add_form_element_available_elements_container.find_element_by_xpath( '//a[text()="{0}"]'.format(form_element_name) ) self._scroll_to_element(form_element_to_add, simple=True) self._scroll_by(0, -150) form_element_to_add.click() # Adding form data if form_element_data: # Wait until the add widget view opens WebDriverWait(self.selenium, timeout=TIMEOUT).until( lambda driver: driver.find_element_by_xpath( """//h1[contains(text(), 'Add "{0}" element to the form')]""".format( form_element_name ) ) ) for field_name, field_value in form_element_data.items(): field_input = self.selenium.find_element_by_name(field_name) field_input.send_keys(field_value) # Click add widget button self.selenium.find_element_by_xpath( '//button[@type="submit"]' ).click() logger.debug(form_element_name) # Wait until the fobi page opens with the form element in. WebDriverWait(self.selenium, timeout=TIMEOUT).until( lambda driver: driver.find_element_by_xpath( """//div[contains(text(), 'The form element plugin "{0}" was added successfully.') and contains(@class, "alert-info")]""".format( form_element_name ) ) ) def __test_add_form_elements(self, create_form=False): """Test of adding multiple form elements. At this point form should be created. """ if create_form: # Adding a form first self.__test_add_form() # One by one adding form elements with data. # Example follows: # # self.__add_form_element( # force_text(BooleanSelectPlugin.name), # { # 'label': "Test boolean", # 'name': "test_boolean", # 'help_text': "Lorem ipsum boolean", # 'required': False, # } # ) for plugin_name, plugin_data in TEST_FORM_ELEMENT_PLUGIN_DATA.items(): # Add form element to the form self.__add_form_element(plugin_name, plugin_data) def __remove_form_element(self, form_element_name, form_element_data, wait=WAIT_FOR): """Add a single plugin to the form. At this stage we should be in the edit form entry interface. """ # Get the label of the given form element in order to delete it later # from the form. delete_form_element_label = self.selenium.find_element_by_xpath( """//label[contains(text(), '({0})') and contains(@class, "control-label")]""".format( form_element_name ) ) # Get the parent of the label delete_form_element_label_parent_container = \ delete_form_element_label.find_element_by_xpath('..') # Click the add form element button to add a new form element to the # form. delete_form_element_link = \ delete_form_element_label_parent_container.find_element_by_partial_link_text( 'Delete' ) delete_form_element_link.click() logger.debug(form_element_name) # Wait until the fobi page opens with the form element in. WebDriverWait(self.selenium, timeout=TIMEOUT).until( lambda driver: driver.find_element_by_xpath( """//div[contains(text(), 'The form element plugin "{0}" was deleted successfully.') and contains(@class, "alert-info")]""".format( form_element_name ) ) ) def __test_remove_form_elements(self): """Test of removing multiple form elements. At this point form should be created. """ for plugin_name, plugin_data in TEST_FORM_ELEMENT_PLUGIN_DATA.items(): # Add form element to the form self.__remove_form_element(plugin_name, plugin_data) # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # ++++++++++++++++++++ Form handler specific ++++++++++++++++++++ # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ def __add_form_handler(self, form_handler_name, form_handler_data, wait=WAIT_FOR): """Add a single handler to the form. At this stage we should be in the edit form entry interface. """ # This part is necessary, since we need to activate the # tab with form handlers. Otherwise Selenium raises # an exception about non-visible element on the page # that we're trying to fetch. form_handlers_tab_link = self.selenium.find_element_by_xpath( """//a[@href="#tab-form-handlers"]""" ) form_handlers_tab_link.click() # Click the add form element button to add a new form element to the # form. add_form_handler_link = self.selenium.find_element_by_xpath( """//a[contains(text(), 'Choose form handler to add') and contains(@class, "dropdown-toggle")]""" ) add_form_handler_link.click() # Find the parent element add_form_handler_parent_container = \ add_form_handler_link.find_element_by_xpath('..') # Find the container of the available form elements add_form_handler_available_elements_container = \ add_form_handler_parent_container.find_element_by_xpath( '//ul[contains(@class, "dropdown-menu")]' ) # Click on the element we want form_handler_to_add = \ add_form_handler_available_elements_container.find_element_by_xpath( '//a[text()="{0}"]'.format(form_handler_name) ) form_handler_to_add.click() # If has config, there's a need to perform some extra tests. if form_handler_data: # Wait until the add widget view opens WebDriverWait(self.selenium, timeout=TIMEOUT).until( lambda driver: driver.find_element_by_xpath( """//h1[contains(text(), 'Add "{0}" handler to the form')]""".format( form_handler_name ) ) ) # Config for field_name, field_value in form_handler_data.items(): field_input = self.selenium.find_element_by_name(field_name) field_input.send_keys(field_value) # Click add widget button self.selenium.find_element_by_xpath( '//button[@type="submit"]' ).click() # Wait until the fobi page opens with the form element in. WebDriverWait(self.selenium, timeout=TIMEOUT).until( lambda driver: driver.find_element_by_xpath( """//div[contains(text(), 'The form handler plugin "{0}" was added successfully.') and contains(@class, "alert-info")]""".format( form_handler_name ) ) ) def __test_add_form_handlers(self, create_form=False): """Test of adding multiple form handlers. At this point form should be created. """ if create_form: # Adding a form first self.__test_add_form() # One by one adding form elements with data. # Example follows: # # self.__add_form_element( # force_text(BooleanSelectPlugin.name), # { # 'label': "Test boolean", # 'name': "test_boolean", # 'help_text': "Lorem ipsum boolean", # 'required': False, # } # ) for plugin_name, plugin_data in TEST_FORM_HANDLER_PLUGIN_DATA.items(): # Add form element to the form self.__add_form_handler(plugin_name, plugin_data) def __remove_form_handler(self, form_handler_name, form_handler_data, wait=WAIT_FOR): """Remove a single handler from the form. At this stage we should be in the edit form entry interface. """ # This part is necessary, since we need to activate the # tab with form handlers. Otherwise Selenium raises # an exception about non-visible element on the page # that we're trying to fetch. form_handlers_tab_link = self.selenium.find_element_by_xpath( """//a[@href="#tab-form-handlers"]""" ) form_handlers_tab_link.click() # Get the label of the given form element in order to delete it later # from the form. delete_form_handler_label = self.selenium.find_element_by_xpath( """//td[contains(text(), '{0}')]""".format(form_handler_name) ) # Get the parent of the label delete_form_handler_label_parent_container = \ delete_form_handler_label.find_element_by_xpath('..') # Click the add form element button to add a new form element to the # form. delete_form_handler_link = \ delete_form_handler_label_parent_container.find_element_by_partial_link_text( 'Delete' ) delete_form_handler_link.click() logger.debug(form_handler_name) # Wait until the fobi page opens with the form element in. WebDriverWait(self.selenium, timeout=TIMEOUT).until( lambda driver: driver.find_element_by_xpath( """//div[contains(text(), 'The form handler plugin "{0}" was deleted successfully.') and contains(@class, "alert-info")]""".format( form_handler_name ) ) ) def __test_remove_form_handlers(self): """Test of removing multiple form handlers. At this point form should be created. """ for plugin_name, plugin_data in TEST_FORM_HANDLER_PLUGIN_DATA.items(): # Remove form handler from the form self.__remove_form_handler(plugin_name, plugin_data) # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # +++++++++++++++++++++++++++ Tests +++++++++++++++++++++++++++++ # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # +++++++++++++++++++++++++++ General +++++++++++++++++++++++++++ # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @skip @print_info def test_1001_open_dashboard(self): """Test open dashboard.""" self.__go_to_dashboard() # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # ++++++++++++++++++++++ Form specific ++++++++++++++++++++++++++ # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @skip @print_info def test_2001_add_form(self): """Test add a new form.""" # Clean up database db_clean_up() self.__test_add_form(wait=WAIT_FOR) # Make sure the success message is there # self.selenium.find_element_by_xpath( # """//div[text()='Form {0} was created successfully.']""".format( # constants.TEST_FORM_NAME # ) # ) @skip @print_info def test_2002_edit_form(self): """Test edit a form.""" # TODO @skip @print_info def test_2003_delete_form(self): """Test delete a form.""" # TODO @skip @print_info def test_2004_submit_form(self, wait=WAIT_FOR): """Test submit form.""" # Clean up database db_clean_up() # Add form elements self.__test_add_form_elements(create_form=True) # self.__sleep(wait) # Getting a form object form = self.__get_form() # Getting the form URL url = reverse('fobi.view_form_entry', args=[form.slug]) self.selenium.get('{0}{1}'.format(self.__get_live_server_url(), url)) # Wait until the edit widget form opens WebDriverWait(self.selenium, timeout=TIMEOUT).until( lambda driver: driver.find_element_by_xpath( '//body[contains(@class, "theme-bootstrap3")]' ) ) for field_name, field_value in TEST_FORM_FIELD_DATA.items(): field_input = self.selenium.find_element_by_name(field_name) field_input.send_keys(field_value) self.__sleep(2) # Click add widget button self.selenium.find_element_by_xpath('//button[@type="submit"]').click() # Wait until the submit success page opens a clear success message. WebDriverWait(self.selenium, timeout=TIMEOUT).until( lambda driver: driver.find_element_by_xpath( """//div[contains(text(), 'Form {0} was submitted successfully.') and contains(@class, "alert-info")]""".format( constants.TEST_FORM_NAME ) ) ) self.__sleep(wait) # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # ++++++++++++++++++++ Form element specific ++++++++++++++++++++ # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @skip @print_info def test_3001_add_form_elements(self, wait=WAIT_FOR): """Test adding form elements.""" # Clean up database db_clean_up() self.__test_add_form_elements(create_form=True) self.__sleep(wait) @skip @print_info def test_3002_remove_form_elements(self): """Test remove form element.""" # Clean up database db_clean_up() self.__test_add_form_elements(create_form=True) self.__test_remove_form_elements() @skip @print_info def test_3003_edit_form_elements(self): """Test edit form element.""" # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # ++++++++++++++++++++ Form handler specific ++++++++++++++++++++ # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @skip @print_info def test_4001_add_form_handlers(self, wait=WAIT_FOR): """Test of adding a single form handler. At this point, if form isn't created, it should be. """ # Clean up database db_clean_up() self.__test_add_form_handlers(create_form=True) self.__sleep(wait) @skip @print_info def test_4002_remove_form_handlers(self): """Test remove form handler.""" # Clean up database db_clean_up() self.__test_add_form_handlers(create_form=True) self.__test_remove_form_handlers() @skip @print_info def test_4003_edit_form_handlers(self): """Test edit form handler."""
if __name__ == '__main__': unittest.main()