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