from contextlib import contextmanager import time from django.contrib.auth.models import User from django.test import LiveServerTestCase from selenium import webdriver from selenium.common import exceptions from selenium.webdriver.common.by import By from selenium.webdriver.support.expected_conditions import ( staleness_of, visibility_of_element_located ) from selenium.webdriver.support.wait import WebDriverWait from selenium.webdriver.support.select import Select from apps.map.models import CaseStudy TIMEOUT = 8 class SeleniumTest(LiveServerTestCase): @classmethod def setUpClass(cls): ### To test with firefox, uncomment these lines and comment those pertaining ### to Chrome. However, it will not work with GitLab CI because the docker ### container does not have the geckodriver installed. # profile = webdriver.FirefoxProfile() # profile.set_preference("dom.forms.number", False) # cls.sl = webdriver.Firefox(profile) chrome_options = webdriver.ChromeOptions() chrome_options.add_argument('--no-sandbox') # comment out this next line in order to see the tests running in a browser. # But be sure to put it back before comitting, or gitlab CI will fail. chrome_options.add_argument('--headless') chrome_options.add_argument('--disable-gpu') cls.sl = webdriver.Chrome(chrome_options=chrome_options) cls.sl.implicitly_wait(TIMEOUT) super(SeleniumTest, cls).setUpClass() @classmethod def tearDownClass(cls): cls.sl.quit() super(SeleniumTest, cls).tearDownClass() def setUp(self): self.user = User.objects.create_superuser(username='test', password='test', email='test@example.com') def _open(self, url): self.sl.get('%s%s' % (self.live_server_url, url)) @contextmanager def wait_for_page_load(self, timeout=30): old_page = self.sl.find_element_by_tag_name('html') yield WebDriverWait(self.sl, timeout).until( staleness_of(old_page) ) def _select_option(self, select, option, optgroup=''): if optgroup: optgroup = '/optgroup' self.sl.find_element_by_xpath( "//select[@id='%s']%s/option[text()='%s']" % (select, optgroup, option) ).click() class MapTest(SeleniumTest): def setUp(self): self.case_study = CaseStudy( approved=True, entry_name='test', location='{"type": "Point", "coordinates": [0, 0]}', sector_of_economy='RN', positive_or_negative='P', country='NZ', area_of_land='100', land_ownership='PRI', location_context='URB', describe_ecosystem='test', project_status='EXSTNG', synopsis='test', full_description='test', media_coverage_mainstream='test', media_coverage_independent='test' ) self.case_study.save() def login(self): self.user = User.objects.create_superuser(username='test', password='test', email='test@example.com'); self.sl.find_element_by_id('id_username').send_keys('test'); self.sl.find_element_by_id('id_password').send_keys('test'); self.sl.find_element_by_css_selector('input[type="submit"]').click() def place_marker(self): # click the zoom out button enough to bring up the thing to draw marker then use it. # the headless browser needs time between each click or it does not show the draw-marker control. for i in range(0, 15): self.sl.find_element_by_class_name('leaflet-control-zoom-in').click() time.sleep(0.2) self.sl.find_element_by_class_name('leaflet-draw-draw-marker').click() self.sl.find_element_by_id('id_location-map').click() def test_form_will_show_error(self): self._open('/en-gb/case-study/create/long'); self.login(); # navigate to the last tab, where the submit button is self.sl.find_element_by_css_selector('a[href="#uploads"]').click() # click submit without filling in any fields self.sl.find_element_by_id('submit-id-submit').click() error_message = self.sl.find_element_by_class_name('has-error') self.assertTrue(error_message.is_displayed()) def test_short_form_will_submit(self): self._open('/en-gb/case-study/create/short'); self.login() self.place_marker() self.sl.find_element_by_id('id_entry_name').send_keys('Short Entry'); Select(self.sl.find_element_by_id('id_country')).select_by_visible_text('Albania'); self.sl.find_element_by_id('id_area_of_land').send_keys('123'); Select(self.sl.find_element_by_id('id_land_ownership')).select_by_visible_text('Private land'); Select(self.sl.find_element_by_id('id_location_context')).select_by_visible_text('Urban'); self.sl.find_element_by_id('id_describe_ecosystem').send_keys('test'); Select(self.sl.find_element_by_id('id_project_status')).select_by_visible_text('In planning and design'); self.sl.find_element_by_css_selector('[name=sector_of_economy][value=ST]').click() self.sl.find_element_by_id('id_synopsis').send_keys('test'); self.sl.find_element_by_id('id_full_description').send_keys('test'); Select(self.sl.find_element_by_id('id_positive_or_negative')).select_by_visible_text('There is/was an organising process in favour of the project'); # you can submit the form on any field. Using this one because the submit button sometimes isn't visible self.sl.find_element_by_id('id_area_of_land').submit(); self.assertTrue("Thanks!" in self.sl.page_source, "Success message not shown") self._open('/admin/map/casestudy/'); self.assertTrue("Short Entry" in self.sl.page_source, "Case study not saved") def test_long_form_will_submit(self): self._open('/en-gb/case-study/create/long'); self.login() self.place_marker() self.sl.find_element_by_id('id_entry_name').send_keys('Long Entry'); Select(self.sl.find_element_by_id('id_country')).select_by_visible_text('Albania'); self.sl.find_element_by_id('id_area_of_land').send_keys('123'); Select(self.sl.find_element_by_id('id_land_ownership')).select_by_visible_text('Private land'); Select(self.sl.find_element_by_id('id_location_context')).select_by_visible_text('Urban'); self.sl.find_element_by_id('id_describe_ecosystem').send_keys('test'); Select(self.sl.find_element_by_id('id_project_status')).select_by_visible_text('In planning and design'); self.sl.find_element_by_id('id_synopsis').send_keys('test'); self.sl.find_element_by_id('id_full_description').send_keys('test'); self.sl.find_element_by_id('id_project_owners').send_keys('test'); self.sl.find_element_by_id('id_shareholders').send_keys('test'); self.sl.find_element_by_css_selector('a[href="#technical-and-economic-analysis"]').click() self.sl.find_element_by_css_selector('[name=sector_of_economy][value=ST]').click() self.sl.find_element_by_css_selector('a[href="#socio-environmental-analysis"]').click() Select(self.sl.find_element_by_id('id_positive_or_negative')).select_by_visible_text('There is/was an organising process in favour of the project'); self.sl.find_element_by_css_selector('a[href="#uploads"]').click() # you can submit the form on any field. Using this one because the submit button sometimes isn't visible self.sl.find_element_by_id('id_name_of_territory_or_area').submit(); self.assertTrue("Thanks!" in self.sl.page_source, "Success message not shown") self._open('/admin/map/casestudy/'); self.assertTrue("Long Entry" in self.sl.page_source, "Case study not saved") def test_map(self): self._open('/') WebDriverWait(self.sl, 5).until( visibility_of_element_located( (By.CSS_SELECTOR, '.hello--hide') ) ) self.sl.find_element_by_css_selector('.hello--hide').click() WebDriverWait(self.sl, 5).until( visibility_of_element_located( (By.CSS_SELECTOR, '.leaflet-marker-icon') ) ) self.sl.find_element_by_css_selector('.leaflet-marker-icon').click() details_link = self.sl.find_element_by_css_selector('.leaflet-popup-content a.btn') self.assertTrue(details_link.is_displayed()) details_link.click() self.assertTrue(self.sl.current_url.endswith('case-study/test'))