1#! /usr/bin/env python3 2# 3# BitBake Toaster functional tests implementation 4# 5# Copyright (C) 2017 Intel Corporation 6# 7# SPDX-License-Identifier: GPL-2.0-only 8# 9 10import os 11import logging 12import subprocess 13import signal 14import time 15import re 16 17from tests.browser.selenium_helpers_base import SeleniumTestCaseBase 18from tests.builds.buildtest import load_build_environment 19 20logger = logging.getLogger("toaster") 21 22class SeleniumFunctionalTestCase(SeleniumTestCaseBase): 23 wait_toaster_time = 5 24 25 @classmethod 26 def setUpClass(cls): 27 # So that the buildinfo helper uses the test database' 28 if os.environ.get('DJANGO_SETTINGS_MODULE', '') != \ 29 'toastermain.settings_test': 30 raise RuntimeError("Please initialise django with the tests settings: " \ 31 "DJANGO_SETTINGS_MODULE='toastermain.settings_test'") 32 33 load_build_environment() 34 35 # start toaster 36 cmd = "bash -c 'source toaster start'" 37 p = subprocess.Popen( 38 cmd, 39 cwd=os.environ.get("BUILDDIR"), 40 shell=True) 41 if p.wait() != 0: 42 raise RuntimeError("Can't initialize toaster") 43 44 super(SeleniumFunctionalTestCase, cls).setUpClass() 45 cls.live_server_url = 'http://localhost:8000/' 46 47 @classmethod 48 def tearDownClass(cls): 49 super(SeleniumFunctionalTestCase, cls).tearDownClass() 50 51 # XXX: source toaster stop gets blocked, to review why? 52 # from now send SIGTERM by hand 53 time.sleep(cls.wait_toaster_time) 54 builddir = os.environ.get("BUILDDIR") 55 56 with open(os.path.join(builddir, '.toastermain.pid'), 'r') as f: 57 toastermain_pid = int(f.read()) 58 os.kill(toastermain_pid, signal.SIGTERM) 59 with open(os.path.join(builddir, '.runbuilds.pid'), 'r') as f: 60 runbuilds_pid = int(f.read()) 61 os.kill(runbuilds_pid, signal.SIGTERM) 62 63 64 def get_URL(self): 65 rc=self.get_page_source() 66 project_url=re.search("(projectPageUrl\s:\s\")(.*)(\",)",rc) 67 return project_url.group(2) 68 69 70 def find_element_by_link_text_in_table(self, table_id, link_text): 71 """ 72 Assume there're multiple suitable "find_element_by_link_text". 73 In this circumstance we need to specify "table". 74 """ 75 try: 76 table_element = self.get_table_element(table_id) 77 element = table_element.find_element_by_link_text(link_text) 78 except NoSuchElementException as e: 79 print('no element found') 80 raise 81 return element 82 83 def get_table_element(self, table_id, *coordinate): 84 if len(coordinate) == 0: 85#return whole-table element 86 element_xpath = "//*[@id='" + table_id + "']" 87 try: 88 element = self.driver.find_element_by_xpath(element_xpath) 89 except NoSuchElementException as e: 90 raise 91 return element 92 row = coordinate[0] 93 94 if len(coordinate) == 1: 95#return whole-row element 96 element_xpath = "//*[@id='" + table_id + "']/tbody/tr[" + str(row) + "]" 97 try: 98 element = self.driver.find_element_by_xpath(element_xpath) 99 except NoSuchElementException as e: 100 return False 101 return element 102#now we are looking for an element with specified X and Y 103 column = coordinate[1] 104 105 element_xpath = "//*[@id='" + table_id + "']/tbody/tr[" + str(row) + "]/td[" + str(column) + "]" 106 try: 107 element = self.driver.find_element_by_xpath(element_xpath) 108 except NoSuchElementException as e: 109 return False 110 return element 111