import os import unittest import urllib.request from flask import url_for from flask_testing import LiveServerTestCase from selenium import webdriver from selenium.webdriver.common.keys import Keys from selenium.webdriver.support.select import Select from app import create_app from app.models import Agent, Charge, Project from pdc_config import TestConfig from tests.common_db_feed import resources_to_instancedb class BaseFrontTestCase(LiveServerTestCase): def create_app(self): # # remove logging lines on test output import logging log = logging.getLogger('werkzeug') log.setLevel(logging.INFO) log.disabled = True os.environ['WERKZEUG_RUN_MAIN'] = 'true' # pass in test configurations self.app = create_app(TestConfig) self.db_path = resources_to_instancedb(self.app) self.app.config.update( # Specify the test database as the default in_memory wont work for web tests SQLALCHEMY_DATABASE_URI='sqlite:///' + self.db_path, # Change the port that the liveserver listens on as we dont want to conflict with running:5000 LIVESERVER_PORT=8943 ) self.app_context = self.app.app_context() self.app_context.push() return self.app def setUp(self): self.driver = self.create_chrome_driver() # db.create_all() def tearDown(self): # fs_utils.clean_dirs() # db.session.remove() # db.drop_all() self.app_context.pop() if os.path.exists(self.db_path): os.remove(self.db_path) self.driver.close() self.driver.quit() # noinspection PyMethodMayBeStatic def is_in_docker(self): """ Test if in docker. :return: True if running in docker, False otherwise. """ if os.path.exists('/proc/self/cgroup'): with open('/proc/self/cgroup') as f: content = f.read() return '/docker/' in content return False def create_chrome_driver(self): """ Create then return the chrome driver. :return: the chrome driver. """ from selenium.webdriver.chrome.options import Options options = Options() options.add_argument('--headless') # options.add_argument('--log-level=3') # options.add_experimental_option('excludeSwitches', ['enable-logging']) if self.is_in_docker(): options.add_argument("--no-sandbox") return webdriver.Chrome(options=options) class AccessTestCase(BaseFrontTestCase): def test_ping(self): self.assertEqual("http://localhost:8943", self.get_server_url()) def test_selenium_access(self): # On ouvre le navigateur avec l'adresse du serveur. self.driver.get(self.get_server_url()) # L'adresse dans l'url doit être celle que l'on attend. self.assertEqual(self.driver.current_url, 'http://localhost:8943/') def test_server_is_up_and_running(self): response = urllib.request.urlopen(self.get_server_url()) self.assertEqual(response.code, 200) def test_agents_page(self): target_url = self.get_server_url() + url_for('main.agents') self.driver.get(target_url) self.assertEqual(self.driver.current_url, 'http://localhost:8943/agents') def test_agent_page(self): agent_id = 60 target_url = self.get_server_url() + url_for('main.agent', agent_id=agent_id) self.driver.get(target_url) self.assertEqual(self.driver.current_url, f'http://localhost:8943/agent/{agent_id}') td_elmts = self.driver.find_elements_by_xpath("//table[@id='charge_table']/tbody/tr/td") self.assertEqual(260, len(td_elmts)) def test_projects_page(self): target_url = self.get_server_url() + url_for('main.projects') self.driver.get(target_url) self.assertEqual(self.driver.current_url, 'http://localhost:8943/projects') def test_projects_trs(self): target_url = self.get_server_url() + url_for('main.projects') self.driver.get(target_url) td_elmts = self.driver.find_elements_by_xpath("//table/tbody/tr") self.assertEqual(101, len(td_elmts)) def test_projects_tds(self): target_url = self.get_server_url() + url_for('main.projects') self.driver.get(target_url) for tr in self.driver.find_elements_by_xpath("//table/tbody/tr"): with self.subTest(tr): tds = tr.find_elements_by_tag_name('td') self.assertEqual(4, len(tds), tds[0].text + " has wrong number of columns") def test_project_page(self): project_id = 8 target_url = self.get_server_url() + url_for('main.project', project_id=project_id) self.driver.get(target_url) self.assertEqual(self.driver.current_url, f'http://localhost:8943/project/{project_id}') td_elmts = self.driver.find_elements_by_xpath("//table[@id='charge_table']/tbody/tr/td") self.assertEqual(1085, len(td_elmts)) def test_project_page_categories(self): project_id = 84 target_url = self.get_server_url() + url_for('main.project', project_id=project_id) self.driver.get(target_url) self.assertEqual(self.driver.current_url, f'http://localhost:8943/project/{project_id}') # pole_dt_db = self.driver.find_element_by_xpath("//dt[text()='Pôle']/following-sibling::dd") pole_dt_db = self.driver.find_element_by_xpath("//dt[contains(text(),'Pôle')]/following-sibling::dd") self.assertEqual('Solaire', pole_dt_db.text) domaine_dt_db = self.driver.find_element_by_xpath("//dt[contains(text(),'Domaine')]/following-sibling::dd") self.assertTrue('LESIA' in domaine_dt_db.text) class FormsTestCase(BaseFrontTestCase): def test_agent_add(self): # load the form target_url = self.get_server_url() + url_for('main.agent_edit') self.driver.get(target_url) # fill it in firstname_input = self.driver.find_elements_by_xpath("//input[@id='firstname']")[0] firstname_input.send_keys("Hitier") secondname_input = self.driver.find_elements_by_xpath("//input[@id='secondname']")[0] secondname_input.send_keys("Richard") # submit submit_button = self.driver.find_elements_by_xpath("//input[@type='submit']")[0] submit_button.send_keys(Keys.ENTER) # check on database latest_agent = Agent.query.order_by(Agent.id.desc()).all()[0] self.assertEqual('Hitier', latest_agent.firstname) # Test agent form def test_agent_edit(self): # load the form target_url = self.get_server_url() + url_for('main.agent_edit', agent_id=1) self.driver.get(target_url) # fill it in firstname_input = self.driver.find_elements_by_xpath("//input[@id='firstname']")[0] self.assertEqual("Dubois", firstname_input.get_attribute('value')) firstname_input.clear() firstname_input.send_keys("Hitier") # # submit submit_button = self.driver.find_elements_by_xpath("//input[@type='submit']")[0] submit_button.send_keys(Keys.ENTER) # # check on database latest_agent = Agent.query.filter(Agent.id == 1).one() self.assertEqual('Hitier', latest_agent.firstname) # Test project form def test_project_edit(self): project_name = "My Project Name" # load the form target_url = self.get_server_url() + url_for('main.project_edit', project_id=1) self.driver.get(target_url) # fill it in name_input = self.driver.find_elements_by_xpath("//input[@id='name']")[0] self.assertTrue("GRAIN" in name_input.get_attribute('value')) name_input.clear() name_input.send_keys(project_name) # submit submit_button = self.driver.find_elements_by_xpath("//input[@type='submit']")[0] submit_button.send_keys(Keys.ENTER) # check on database latest_agent = Project.query.filter(Project.id == 1).one() self.assertEqual(project_name, latest_agent.name) # Test charge form add new def test_charge_add(self): # load the form target_url = self.get_server_url() + url_for('main.charge_add') self.driver.get(target_url) # fill it in agent_select = Select(self.driver.find_elements_by_xpath("//select[@id='agent_id']")[0]) agent_select.select_by_index(1) project_select = Select(self.driver.find_elements_by_xpath("//select[@id='project_id']")[0]) project_select.select_by_index(1) service_select = Select(self.driver.find_elements_by_xpath("//select[@id='service_id']")[0]) service_select.select_by_index(1) period_select = Select(self.driver.find_elements_by_xpath("//select[@id='period_id']")[0]) period_select.select_by_index(1) capacity_select = Select(self.driver.find_elements_by_xpath("//select[@id='capacity_id']")[0]) capacity_select.select_by_index(1) charge_input = self.driver.find_elements_by_xpath("//input[@id='charge_rate']")[0] charge_input.send_keys("99") # submit submit_button = self.driver.find_elements_by_xpath("//input[@type='submit']")[0] submit_button.send_keys(Keys.ENTER) # check on database latest_charge = Charge.query.order_by(Charge.id.desc()).all()[0] self.assertEqual([514, 41, 17, 1, 1, 99], [latest_charge.agent_id, latest_charge.project_id, latest_charge.service_id, latest_charge.capacity_id, latest_charge.period_id, latest_charge.charge_rate] ) # Test charge form edit existing @unittest.skip("charge edit to be implemented") def test_charge_edit(self): pass