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(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"))