2377 lines
107 KiB
Python
Executable File
2377 lines
107 KiB
Python
Executable File
#!/usr/bin/python
|
|
# Copyright
|
|
|
|
# DESCRIPTION
|
|
# This is toaster automation base class and test cases file
|
|
|
|
# History:
|
|
# 2015.03.09 inital version
|
|
# 2015.03.23 adding toaster_test.cfg, run_toastertest.py so we can run case by case from outside
|
|
|
|
# Briefs:
|
|
# This file is comprised of 3 parts:
|
|
# I: common utils like sorting, getting attribute.. etc
|
|
# II: base class part, which complies with unittest frame work and
|
|
# contains class selenium-based functions
|
|
# III: test cases
|
|
# to add new case: just implement new test_xxx() function in class toaster_cases
|
|
|
|
# NOTES for cases:
|
|
# case 946:
|
|
# step 6 - 8 needs to be observed using screenshots
|
|
# case 956:
|
|
# step 2 - 3 needs to be run manually
|
|
|
|
import unittest, time, re, sys, getopt, os, logging, string, errno, exceptions
|
|
import shutil, argparse, ConfigParser, platform, json
|
|
from selenium import webdriver
|
|
from selenium.common.exceptions import NoSuchElementException
|
|
from selenium import selenium
|
|
from selenium.webdriver.common.by import By
|
|
from selenium.webdriver.common.keys import Keys
|
|
from selenium.webdriver.support.ui import Select
|
|
import sqlite3 as sqlite
|
|
|
|
|
|
###########################################
|
|
# #
|
|
# PART I: utils stuff #
|
|
# #
|
|
###########################################
|
|
|
|
class Listattr(object):
|
|
"""
|
|
Set of list attribute. This is used to determine what the list content is.
|
|
Later on we may add more attributes here.
|
|
"""
|
|
NULL = "null"
|
|
NUMBERS = "numbers"
|
|
STRINGS = "strings"
|
|
PERCENT = "percentage"
|
|
SIZE = "size"
|
|
UNKNOWN = "unknown"
|
|
|
|
|
|
def get_log_root_dir():
|
|
max_depth = 5
|
|
parent_dir = '../'
|
|
for number in range(0, max_depth):
|
|
if os.path.isdir(sys.path[0] + os.sep + (os.pardir + os.sep)*number + 'log'):
|
|
log_root_dir = os.path.abspath(sys.path[0] + os.sep + (os.pardir + os.sep)*number + 'log')
|
|
break
|
|
|
|
if number == (max_depth - 1):
|
|
print('No log dir found. Please check')
|
|
raise Exception
|
|
|
|
return log_root_dir
|
|
|
|
|
|
def mkdir_p(dir):
|
|
try:
|
|
os.makedirs(dir)
|
|
except OSError as exc:
|
|
if exc.errno == errno.EEXIST and os.path.isdir(dir):
|
|
pass
|
|
else:
|
|
raise
|
|
|
|
|
|
def get_list_attr(testlist):
|
|
"""
|
|
To determine the list content
|
|
"""
|
|
if not testlist:
|
|
return Listattr.NULL
|
|
listtest = testlist[:]
|
|
try:
|
|
listtest.remove('')
|
|
except ValueError:
|
|
pass
|
|
pattern_percent = re.compile(r"^([0-9])+(\.)?([0-9])*%$")
|
|
pattern_size = re.compile(r"^([0-9])+(\.)?([0-9])*( )*(K)*(M)*(G)*B$")
|
|
pattern_number = re.compile(r"^([0-9])+(\.)?([0-9])*$")
|
|
def get_patterned_number(pattern, tlist):
|
|
count = 0
|
|
for item in tlist:
|
|
if re.search(pattern, item):
|
|
count += 1
|
|
return count
|
|
if get_patterned_number(pattern_percent, listtest) == len(listtest):
|
|
return Listattr.PERCENT
|
|
elif get_patterned_number(pattern_size, listtest) == len(listtest):
|
|
return Listattr.SIZE
|
|
elif get_patterned_number(pattern_number, listtest) == len(listtest):
|
|
return Listattr.NUMBERS
|
|
else:
|
|
return Listattr.STRINGS
|
|
|
|
|
|
def is_list_sequenced(testlist):
|
|
"""
|
|
Function to tell if list is sequenced
|
|
Currently we may have list made up of: Strings ; numbers ; percentage ; time; size
|
|
Each has respective way to determine if it's sequenced.
|
|
"""
|
|
test_list = testlist[:]
|
|
try:
|
|
test_list.remove('')
|
|
except ValueError:
|
|
pass
|
|
|
|
if get_list_attr(testlist) == Listattr.NULL :
|
|
return True
|
|
|
|
elif get_list_attr(testlist) == Listattr.STRINGS :
|
|
return (sorted(test_list) == test_list)
|
|
|
|
elif get_list_attr(testlist) == Listattr.NUMBERS :
|
|
list_number = []
|
|
for item in test_list:
|
|
list_number.append(eval(item))
|
|
return (sorted(list_number) == list_number)
|
|
|
|
elif get_list_attr(testlist) == Listattr.PERCENT :
|
|
list_number = []
|
|
for item in test_list:
|
|
list_number.append(eval(item.strip('%')))
|
|
return (sorted(list_number) == list_number)
|
|
|
|
elif get_list_attr(testlist) == Listattr.SIZE :
|
|
list_number = []
|
|
# currently SIZE is splitted by space
|
|
for item in test_list:
|
|
if item.split()[1].upper() == "KB":
|
|
list_number.append(1024 * eval(item.split()[0]))
|
|
elif item.split()[1].upper() == "MB":
|
|
list_number.append(1024 * 1024 * eval(item.split()[0]))
|
|
elif item.split()[1].upper() == "GB":
|
|
list_number.append(1024 * 1024 * 1024 * eval(item.split()[0]))
|
|
else:
|
|
list_number.append(eval(item.split()[0]))
|
|
return (sorted(list_number) == list_number)
|
|
|
|
else:
|
|
print('Unrecognized list type, please check')
|
|
return False
|
|
|
|
|
|
def is_list_inverted(testlist):
|
|
"""
|
|
Function to tell if list is inverted
|
|
Currently we may have list made up of: Strings ; numbers ; percentage ; time; size
|
|
Each has respective way to determine if it's inverted.
|
|
"""
|
|
test_list = testlist[:]
|
|
try:
|
|
test_list.remove('')
|
|
except ValueError:
|
|
pass
|
|
|
|
if get_list_attr(testlist) == Listattr.NULL :
|
|
return True
|
|
|
|
elif get_list_attr(testlist) == Listattr.STRINGS :
|
|
return (sorted(test_list, reverse = True) == test_list)
|
|
|
|
elif get_list_attr(testlist) == Listattr.NUMBERS :
|
|
list_number = []
|
|
for item in test_list:
|
|
list_number.append(eval(item))
|
|
return (sorted(list_number, reverse = True) == list_number)
|
|
|
|
elif get_list_attr(testlist) == Listattr.PERCENT :
|
|
list_number = []
|
|
for item in test_list:
|
|
list_number.append(eval(item.strip('%')))
|
|
return (sorted(list_number, reverse = True) == list_number)
|
|
|
|
elif get_list_attr(testlist) == Listattr.SIZE :
|
|
list_number = []
|
|
# currently SIZE is splitted by space. such as 0 B; 1 KB; 2 MB
|
|
for item in test_list:
|
|
if item.split()[1].upper() == "KB":
|
|
list_number.append(1024 * eval(item.split()[0]))
|
|
elif item.split()[1].upper() == "MB":
|
|
list_number.append(1024 * 1024 * eval(item.split()[0]))
|
|
elif item.split()[1].upper() == "GB":
|
|
list_number.append(1024 * 1024 * 1024 * eval(item.split()[0]))
|
|
else:
|
|
list_number.append(eval(item.split()[0]))
|
|
return (sorted(list_number, reverse = True) == list_number)
|
|
|
|
else:
|
|
print('Unrecognized list type, please check')
|
|
return False
|
|
|
|
def replace_file_content(filename, item, option):
|
|
f = open(filename)
|
|
lines = f.readlines()
|
|
f.close()
|
|
output = open(filename, 'w')
|
|
for line in lines:
|
|
if line.startswith(item):
|
|
output.write(item + " = '" + option + "'\n")
|
|
else:
|
|
output.write(line)
|
|
output.close()
|
|
|
|
def extract_number_from_string(s):
|
|
"""
|
|
extract the numbers in a string. return type is 'list'
|
|
"""
|
|
return re.findall(r'([0-9]+)', s)
|
|
|
|
# Below is decorator derived from toaster backend test code
|
|
class NoParsingFilter(logging.Filter):
|
|
def filter(self, record):
|
|
return record.levelno == 100
|
|
|
|
def LogResults(original_class):
|
|
orig_method = original_class.run
|
|
|
|
from time import strftime, gmtime
|
|
caller = 'toaster'
|
|
timestamp = strftime('%Y%m%d%H%M%S',gmtime())
|
|
logfile = os.path.join(os.getcwd(),'results-'+caller+'.'+timestamp+'.log')
|
|
linkfile = os.path.join(os.getcwd(),'results-'+caller+'.log')
|
|
|
|
#rewrite the run method of unittest.TestCase to add testcase logging
|
|
def run(self, result, *args, **kws):
|
|
orig_method(self, result, *args, **kws)
|
|
passed = True
|
|
testMethod = getattr(self, self._testMethodName)
|
|
#if test case is decorated then use it's number, else use it's name
|
|
try:
|
|
test_case = testMethod.test_case
|
|
except AttributeError:
|
|
test_case = self._testMethodName
|
|
|
|
class_name = str(testMethod.im_class).split("'")[1]
|
|
|
|
#create custom logging level for filtering.
|
|
custom_log_level = 100
|
|
logging.addLevelName(custom_log_level, 'RESULTS')
|
|
|
|
def results(self, message, *args, **kws):
|
|
if self.isEnabledFor(custom_log_level):
|
|
self.log(custom_log_level, message, *args, **kws)
|
|
logging.Logger.results = results
|
|
|
|
logging.basicConfig(filename=logfile,
|
|
filemode='w',
|
|
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
|
|
datefmt='%H:%M:%S',
|
|
level=custom_log_level)
|
|
for handler in logging.root.handlers:
|
|
handler.addFilter(NoParsingFilter())
|
|
local_log = logging.getLogger(caller)
|
|
|
|
#check status of tests and record it
|
|
|
|
for (name, msg) in result.errors:
|
|
if (self._testMethodName == str(name).split(' ')[0]) and (class_name in str(name).split(' ')[1]):
|
|
local_log.results("Testcase "+str(test_case)+": ERROR")
|
|
local_log.results("Testcase "+str(test_case)+":\n"+msg)
|
|
passed = False
|
|
for (name, msg) in result.failures:
|
|
if (self._testMethodName == str(name).split(' ')[0]) and (class_name in str(name).split(' ')[1]):
|
|
local_log.results("Testcase "+str(test_case)+": FAILED")
|
|
local_log.results("Testcase "+str(test_case)+":\n"+msg)
|
|
passed = False
|
|
for (name, msg) in result.skipped:
|
|
if (self._testMethodName == str(name).split(' ')[0]) and (class_name in str(name).split(' ')[1]):
|
|
local_log.results("Testcase "+str(test_case)+": SKIPPED")
|
|
passed = False
|
|
if passed:
|
|
local_log.results("Testcase "+str(test_case)+": PASSED")
|
|
|
|
# Create symlink to the current log
|
|
if os.path.exists(linkfile):
|
|
os.remove(linkfile)
|
|
os.symlink(logfile, linkfile)
|
|
|
|
original_class.run = run
|
|
|
|
return original_class
|
|
|
|
|
|
###########################################
|
|
# #
|
|
# PART II: base class #
|
|
# #
|
|
###########################################
|
|
|
|
@LogResults
|
|
class toaster_cases_base(unittest.TestCase):
|
|
|
|
@classmethod
|
|
def setUpClass(cls):
|
|
cls.log = cls.logger_create()
|
|
|
|
def setUp(self):
|
|
self.screenshot_sequence = 1
|
|
self.verificationErrors = []
|
|
self.accept_next_alert = True
|
|
self.host_os = platform.system().lower()
|
|
if os.getenv('TOASTER_SUITE'):
|
|
self.target_suite = os.getenv('TOASTER_SUITE')
|
|
else:
|
|
self.target_suite = self.host_os
|
|
|
|
self.parser = ConfigParser.SafeConfigParser()
|
|
self.parser.read('toaster_test.cfg')
|
|
self.base_url = eval(self.parser.get('toaster_test_' + self.target_suite, 'toaster_url'))
|
|
|
|
# create log dir . Currently , we put log files in log/tmp. After all
|
|
# test cases are done, move them to log/$datetime dir
|
|
self.log_tmp_dir = os.path.abspath(sys.path[0]) + os.sep + 'log' + os.sep + 'tmp'
|
|
try:
|
|
mkdir_p(self.log_tmp_dir)
|
|
except OSError :
|
|
logging.error("%(asctime)s Cannot create tmp dir under log, please check your privilege")
|
|
# self.log = self.logger_create()
|
|
# driver setup
|
|
self.setup_browser()
|
|
|
|
@staticmethod
|
|
def logger_create():
|
|
log_file = "toaster-auto-" + time.strftime("%Y%m%d%H%M%S") + ".log"
|
|
if os.path.exists("toaster-auto.log"): os.remove("toaster-auto.log")
|
|
os.symlink(log_file, "toaster-auto.log")
|
|
|
|
log = logging.getLogger("toaster")
|
|
log.setLevel(logging.DEBUG)
|
|
|
|
fh = logging.FileHandler(filename=log_file, mode='w')
|
|
fh.setLevel(logging.DEBUG)
|
|
|
|
ch = logging.StreamHandler(sys.stdout)
|
|
ch.setLevel(logging.INFO)
|
|
|
|
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
|
|
fh.setFormatter(formatter)
|
|
ch.setFormatter(formatter)
|
|
|
|
log.addHandler(fh)
|
|
log.addHandler(ch)
|
|
|
|
return log
|
|
|
|
|
|
def setup_browser(self, *browser_path):
|
|
self.browser = eval(self.parser.get('toaster_test_' + self.target_suite, 'test_browser'))
|
|
print(self.browser)
|
|
if self.browser == "firefox":
|
|
driver = webdriver.Firefox()
|
|
elif self.browser == "chrome":
|
|
driver = webdriver.Chrome()
|
|
elif self.browser == "ie":
|
|
driver = webdriver.Ie()
|
|
else:
|
|
driver = None
|
|
print("unrecognized browser type, please check")
|
|
self.driver = driver
|
|
self.driver.implicitly_wait(30)
|
|
return self.driver
|
|
|
|
|
|
def save_screenshot(self, **log_args):
|
|
"""
|
|
This function is used to save screen either by os interface or selenium interface.
|
|
How to use:
|
|
self.save_screenshot(screenshot_type = 'native'/'selenium', log_sub_dir = 'xxx',
|
|
append_name = 'stepx')
|
|
where native means screenshot func provided by OS,
|
|
selenium means screenshot func provided by selenium webdriver
|
|
"""
|
|
types = [log_args.get('screenshot_type')]
|
|
# when no screenshot_type is specified
|
|
if types == [None]:
|
|
types = ['native', 'selenium']
|
|
# normally append_name is used to specify which step..
|
|
add_name = log_args.get('append_name')
|
|
if not add_name:
|
|
add_name = '-'
|
|
# normally there's no need to specify sub_dir
|
|
sub_dir = log_args.get('log_sub_dir')
|
|
if not sub_dir:
|
|
# use casexxx as sub_dir name
|
|
sub_dir = 'case' + str(self.case_no)
|
|
for item in types:
|
|
log_dir = self.log_tmp_dir + os.sep + sub_dir
|
|
mkdir_p(log_dir)
|
|
log_path = log_dir + os.sep + self.browser + '-' +\
|
|
item + '-' + add_name + '-' + str(self.screenshot_sequence) + '.png'
|
|
if item == 'native':
|
|
if self.host_os == "linux":
|
|
os.system("scrot " + log_path)
|
|
elif self.host_os=="darwin":
|
|
os.system("screencapture -x " + log_path)
|
|
elif item == 'selenium':
|
|
self.driver.get_screenshot_as_file(log_path)
|
|
self.screenshot_sequence += 1
|
|
|
|
def browser_delay(self):
|
|
"""
|
|
currently this is a workaround for some chrome test.
|
|
Sometimes we need a delay to accomplish some operation.
|
|
But for firefox, mostly we don't need this.
|
|
To be discussed
|
|
"""
|
|
if self.browser == "chrome":
|
|
time.sleep(1)
|
|
return
|
|
|
|
|
|
# these functions are not contained in WebDriver class..
|
|
def find_element_by_text(self, string):
|
|
return self.driver.find_element_by_xpath("//*[text()='" + string + "']")
|
|
|
|
|
|
def find_elements_by_text(self, string):
|
|
return self.driver.find_elements_by_xpath("//*[text()='" + string + "']")
|
|
|
|
|
|
def find_element_by_text_in_table(self, table_id, text_string):
|
|
"""
|
|
This is used to search some certain 'text' in certain table
|
|
"""
|
|
try:
|
|
table_element = self.get_table_element(table_id)
|
|
element = table_element.find_element_by_xpath("//*[text()='" + text_string + "']")
|
|
except NoSuchElementException as e:
|
|
print('no element found')
|
|
raise
|
|
return element
|
|
|
|
|
|
def find_element_by_link_text_in_table(self, table_id, link_text):
|
|
"""
|
|
Assume there're multiple suitable "find_element_by_link_text".
|
|
In this circumstance we need to specify "table".
|
|
"""
|
|
try:
|
|
table_element = self.get_table_element(table_id)
|
|
element = table_element.find_element_by_link_text(link_text)
|
|
except NoSuchElementException as e:
|
|
print('no element found')
|
|
raise
|
|
return element
|
|
|
|
|
|
def find_elements_by_link_text_in_table(self, table_id, link_text):
|
|
"""
|
|
Search link-text in certain table. This helps to narrow down search area.
|
|
"""
|
|
try:
|
|
table_element = self.get_table_element(table_id)
|
|
element_list = table_element.find_elements_by_link_text(link_text)
|
|
except NoSuchElementException as e:
|
|
print('no element found')
|
|
raise
|
|
return element_list
|
|
|
|
|
|
def find_element_by_partial_link_text_in_table(self, table_id, link_text):
|
|
"""
|
|
Search element by partial link text in certain table.
|
|
"""
|
|
try:
|
|
table_element = self.get_table_element(table_id)
|
|
element = table_element.find_element_by_partial_link_text(link_text)
|
|
return element
|
|
except NoSuchElementException as e:
|
|
print('no element found')
|
|
raise
|
|
|
|
|
|
def find_elements_by_partial_link_text_in_table(self, table_id, link_text):
|
|
"""
|
|
Assume there're multiple suitable "find_partial_element_by_link_text".
|
|
"""
|
|
try:
|
|
table_element = self.get_table_element(table_id)
|
|
element_list = table_element.find_elements_by_partial_link_text(link_text)
|
|
return element_list
|
|
except NoSuchElementException as e:
|
|
print('no element found')
|
|
raise
|
|
|
|
|
|
def find_element_by_xpath_in_table(self, table_id, xpath):
|
|
"""
|
|
This helps to narrow down search area. Especially useful when dealing with pop-up form.
|
|
"""
|
|
try:
|
|
table_element = self.get_table_element(table_id)
|
|
element = table_element.find_element_by_xpath(xpath)
|
|
except NoSuchElementException as e:
|
|
print('no element found')
|
|
raise
|
|
return element
|
|
|
|
|
|
def find_elements_by_xpath_in_table(self, table_id, xpath):
|
|
"""
|
|
This helps to narrow down search area. Especially useful when dealing with pop-up form.
|
|
"""
|
|
try:
|
|
table_element = self.get_table_element(table_id)
|
|
element_list = table_element.find_elements_by_xpath(xpath)
|
|
except NoSuchElementException as e:
|
|
print('no elements found')
|
|
raise
|
|
return element_list
|
|
|
|
|
|
def shortest_xpath(self, pname, pvalue):
|
|
return "//*[@" + pname + "='" + pvalue + "']"
|
|
|
|
|
|
#usually elements in the same column are with same class name. for instance: class="outcome" .TBD
|
|
def get_table_column_text(self, attr_name, attr_value):
|
|
c_xpath = self.shortest_xpath(attr_name, attr_value)
|
|
elements = self.driver.find_elements_by_xpath(c_xpath)
|
|
c_list = []
|
|
for element in elements:
|
|
c_list.append(element.text)
|
|
return c_list
|
|
|
|
|
|
def get_table_column_text_by_column_number(self, table_id, column_number):
|
|
c_xpath = "//*[@id='" + table_id + "']//td[" + str(column_number) + "]"
|
|
elements = self.driver.find_elements_by_xpath(c_xpath)
|
|
c_list = []
|
|
for element in elements:
|
|
c_list.append(element.text)
|
|
return c_list
|
|
|
|
|
|
def get_table_head_text(self, *table_id):
|
|
#now table_id is a tuple...
|
|
if table_id:
|
|
thead_xpath = "//*[@id='" + table_id[0] + "']//thead//th[text()]"
|
|
elements = self.driver.find_elements_by_xpath(thead_xpath)
|
|
c_list = []
|
|
for element in elements:
|
|
if element.text:
|
|
c_list.append(element.text)
|
|
return c_list
|
|
#default table on page
|
|
else:
|
|
return self.driver.find_element_by_xpath("//*/table/thead").text
|
|
|
|
|
|
|
|
def get_table_element(self, table_id, *coordinate):
|
|
if len(coordinate) == 0:
|
|
#return whole-table element
|
|
element_xpath = "//*[@id='" + table_id + "']"
|
|
try:
|
|
element = self.driver.find_element_by_xpath(element_xpath)
|
|
except NoSuchElementException as e:
|
|
raise
|
|
return element
|
|
row = coordinate[0]
|
|
|
|
if len(coordinate) == 1:
|
|
#return whole-row element
|
|
element_xpath = "//*[@id='" + table_id + "']/tbody/tr[" + str(row) + "]"
|
|
try:
|
|
element = self.driver.find_element_by_xpath(element_xpath)
|
|
except NoSuchElementException as e:
|
|
return False
|
|
return element
|
|
#now we are looking for an element with specified X and Y
|
|
column = coordinate[1]
|
|
|
|
element_xpath = "//*[@id='" + table_id + "']/tbody/tr[" + str(row) + "]/td[" + str(column) + "]"
|
|
try:
|
|
element = self.driver.find_element_by_xpath(element_xpath)
|
|
except NoSuchElementException as e:
|
|
return False
|
|
return element
|
|
|
|
|
|
def get_table_data(self, table_id, row_count, column_count):
|
|
row = 1
|
|
Lists = []
|
|
while row <= row_count:
|
|
column = 1
|
|
row_content=[]
|
|
while column <= column_count:
|
|
s= "//*[@id='" + table_id + "']/tbody/tr[" + str(row) +"]/td[" + str(column) + "]"
|
|
v = self.driver.find_element_by_xpath(s).text
|
|
row_content.append(v)
|
|
column = column + 1
|
|
print("row_content=",row_content)
|
|
Lists.extend(row_content)
|
|
print(Lists[row-1][0])
|
|
row = row + 1
|
|
return Lists
|
|
|
|
# The is_xxx_present functions only returns True/False
|
|
# All the log work is done in test procedure, so we can easily trace back
|
|
# using logging
|
|
def is_text_present (self, patterns):
|
|
for pattern in patterns:
|
|
if str(pattern) not in self.driver.page_source:
|
|
print('Text "'+pattern+'" is missing')
|
|
return False
|
|
return True
|
|
|
|
|
|
def is_element_present(self, how, what):
|
|
try:
|
|
self.driver.find_element(how, what)
|
|
except NoSuchElementException as e:
|
|
print('Could not find element '+str(what)+' by ' + str(how))
|
|
return False
|
|
return True
|
|
|
|
|
|
def is_alert_present(self):
|
|
try: self.driver.switch_to_alert()
|
|
except NoAlertPresentException as e: return False
|
|
return True
|
|
|
|
|
|
def close_alert_and_get_its_text(self):
|
|
try:
|
|
alert = self.driver.switch_to_alert()
|
|
alert_text = alert.text
|
|
if self.accept_next_alert:
|
|
alert.accept()
|
|
else:
|
|
alert.dismiss()
|
|
return alert_text
|
|
finally: self.accept_next_alert = True
|
|
|
|
|
|
def get_case_number(self):
|
|
"""
|
|
what case are we running now
|
|
"""
|
|
funcname = sys._getframe(1).f_code.co_name
|
|
caseno_str = funcname.strip('test_')
|
|
try:
|
|
caseno = int(caseno_str)
|
|
except ValueError:
|
|
print("get case number error! please check if func name is test_xxx")
|
|
return False
|
|
return caseno
|
|
|
|
|
|
def tearDown(self):
|
|
self.log.info(' END: CASE %s log \n\n' % str(self.case_no))
|
|
self.driver.quit()
|
|
self.assertEqual([], self.verificationErrors)
|
|
|
|
|
|
###################################################################
|
|
# #
|
|
# PART III: test cases #
|
|
# please refer to #
|
|
# https://bugzilla.yoctoproject.org/tr_show_case.cgi?case_id=xxx #
|
|
# #
|
|
###################################################################
|
|
|
|
# Note: to comply with the unittest framework, we call these test_xxx functions
|
|
# from run_toastercases.py to avoid calling setUp() and tearDown() multiple times
|
|
|
|
|
|
class toaster_cases(toaster_cases_base):
|
|
##############
|
|
# CASE 901 #
|
|
##############
|
|
def test_901(self):
|
|
# the reason why get_case_number is not in setUp function is that
|
|
# otherwise it returns "setUp" instead of "test_xxx"
|
|
self.case_no = self.get_case_number()
|
|
self.log.info(' CASE %s log: ' % str(self.case_no))
|
|
self.driver.maximize_window()
|
|
self.driver.get(self.base_url)
|
|
# open all columns
|
|
self.driver.find_element_by_id("edit-columns-button").click()
|
|
# adding explicitly wait for chromedriver..-_-
|
|
self.browser_delay()
|
|
self.driver.find_element_by_id("started_on").click()
|
|
self.browser_delay()
|
|
self.driver.find_element_by_id("time").click()
|
|
self.driver.find_element_by_id("edit-columns-button").click()
|
|
# dict: {lint text name : actual class name}
|
|
table_head_dict = {'Outcome':'outcome', 'Recipe':'target', 'Machine':'machine', 'Started on':'started_on', 'Completed on':'completed_on', \
|
|
'Errors':'errors_no', 'Warnings':'warnings_no', 'Time':'time'}
|
|
for key in table_head_dict:
|
|
try:
|
|
self.driver.find_element_by_link_text(key).click()
|
|
except Exception as e:
|
|
self.log.error("%s cannot be found on page" % key)
|
|
raise
|
|
column_list = self.get_table_column_text("class", table_head_dict[key])
|
|
# after 1st click, the list should be either sequenced or inverted, but we don't have a "default order" here
|
|
# the point is, after another click, it should be another order
|
|
if is_list_inverted(column_list):
|
|
self.driver.find_element_by_link_text(key).click()
|
|
column_list = self.get_table_column_text("class", table_head_dict[key])
|
|
self.assertTrue(is_list_sequenced(column_list), msg=("%s column not in order" % key))
|
|
else:
|
|
self.assertTrue(is_list_sequenced(column_list), msg=("%s column not sequenced" % key))
|
|
self.driver.find_element_by_link_text(key).click()
|
|
column_list = self.get_table_column_text("class", table_head_dict[key])
|
|
self.assertTrue(is_list_inverted(column_list), msg=("%s column not inverted" % key))
|
|
self.log.info("case passed")
|
|
|
|
|
|
##############
|
|
# CASE 902 #
|
|
##############
|
|
def test_902(self):
|
|
self.case_no = self.get_case_number()
|
|
self.log.info(' CASE %s log: ' % str(self.case_no))
|
|
self.driver.maximize_window()
|
|
self.driver.get(self.base_url)
|
|
# Could add more test patterns here in the future. Also, could search some items other than target column in future..
|
|
patterns = ["minimal", "sato"]
|
|
for pattern in patterns:
|
|
ori_target_column_texts = self.get_table_column_text("class", "target")
|
|
print(ori_target_column_texts)
|
|
self.driver.find_element_by_id("search").clear()
|
|
self.driver.find_element_by_id("search").send_keys(pattern)
|
|
self.driver.find_element_by_id("search-button").click()
|
|
new_target_column_texts = self.get_table_column_text("class", "target")
|
|
# if nothing found, we still count it as "pass"
|
|
if new_target_column_texts:
|
|
for text in new_target_column_texts:
|
|
self.assertTrue(text.find(pattern), msg=("%s item doesn't exist " % pattern))
|
|
self.driver.find_element_by_css_selector("i.icon-remove").click()
|
|
target_column_texts = self.get_table_column_text("class", "target")
|
|
self.assertTrue(ori_target_column_texts == target_column_texts, msg=("builds changed after operations"))
|
|
|
|
|
|
##############
|
|
# CASE 903 #
|
|
##############
|
|
def test_903(self):
|
|
self.case_no = self.get_case_number()
|
|
self.log.info(' CASE %s log: ' % str(self.case_no))
|
|
self.driver.maximize_window()
|
|
self.driver.get(self.base_url)
|
|
# when opening a new page, "started_on" is not displayed by default
|
|
self.driver.find_element_by_id("edit-columns-button").click()
|
|
# currently all the delay are for chrome driver -_-
|
|
self.browser_delay()
|
|
self.driver.find_element_by_id("started_on").click()
|
|
self.driver.find_element_by_id("edit-columns-button").click()
|
|
# step 4
|
|
items = ["Outcome", "Completed on", "Started on"]
|
|
for item in items:
|
|
try:
|
|
temp_element = self.find_element_by_text_in_table('otable', item)
|
|
# this is how we find "filter icon" in the same level as temp_element(where "a" means clickable, "i" means icon)
|
|
self.assertTrue(temp_element.find_element_by_xpath("..//*/a/i[@class='icon-filter filtered']"))
|
|
except Exception as e:
|
|
self.assertFalse(True, msg=(" %s cannot be found! %s" % (item, e)))
|
|
raise
|
|
# step 5-6
|
|
temp_element = self.find_element_by_link_text_in_table('otable', 'Outcome')
|
|
temp_element.find_element_by_xpath("..//*/a/i[@class='icon-filter filtered']").click()
|
|
self.browser_delay()
|
|
# the 2nd option, whatever it is
|
|
self.driver.find_element_by_xpath("(//input[@name='filter'])[2]").click()
|
|
# click "Apply" button
|
|
self.driver.find_element_by_xpath("//*[@id='filter_outcome']//*[text()='Apply']").click()
|
|
# save screen here
|
|
time.sleep(1)
|
|
self.save_screenshot(screenshot_type='selenium', append_name='step5')
|
|
temp_element = self.find_element_by_link_text_in_table('otable', 'Completed on')
|
|
temp_element.find_element_by_xpath("..//*/a/i[@class='icon-filter filtered']").click()
|
|
self.browser_delay()
|
|
self.driver.find_element_by_xpath("//*[@id='filter_completed_on']//*[text()='Apply']").click()
|
|
# save screen here to compare to previous one
|
|
# please note that for chrome driver, need a little break before saving
|
|
# screen here -_-
|
|
self.browser_delay()
|
|
self.save_screenshot(screenshot_type='selenium', append_name='step6')
|
|
self.driver.find_element_by_id("search").clear()
|
|
self.driver.find_element_by_id("search").send_keys("core-image")
|
|
self.driver.find_element_by_id("search-button").click()
|
|
|
|
|
|
##############
|
|
# CASE 904 #
|
|
##############
|
|
def test_904(self):
|
|
self.case_no = self.get_case_number()
|
|
self.log.info(' CASE %s log: ' % str(self.case_no))
|
|
self.driver.maximize_window()
|
|
self.driver.get(self.base_url)
|
|
self.driver.find_element_by_partial_link_text("core-image").click()
|
|
self.driver.find_element_by_link_text("Tasks").click()
|
|
self.table_name = 'otable'
|
|
# This is how we find the "default" rows-number!
|
|
rows_displayed = int(Select(self.driver.find_element_by_css_selector("select.pagesize")).first_selected_option.text)
|
|
print(rows_displayed)
|
|
self.assertTrue(self.get_table_element(self.table_name, rows_displayed), msg=("not enough rows displayed"))
|
|
self.assertFalse(self.get_table_element(self.table_name, rows_displayed + 1), \
|
|
msg=("more rows displayed than expected"))
|
|
# Search text box background text is "Search tasks"
|
|
self.assertTrue(self.driver.find_element_by_xpath("//*[@id='searchform']/*[@placeholder='Search tasks']"),\
|
|
msg=("background text doesn't exist"))
|
|
|
|
self.driver.find_element_by_id("search").clear()
|
|
self.driver.find_element_by_id("search").send_keys("busybox")
|
|
self.driver.find_element_by_id("search-button").click()
|
|
self.browser_delay()
|
|
self.save_screenshot(screenshot_type='selenium', append_name='step5')
|
|
self.driver.find_element_by_css_selector("i.icon-remove").click()
|
|
# Save screen here
|
|
self.save_screenshot(screenshot_type='selenium', append_name='step5_2')
|
|
self.driver.find_element_by_id("edit-columns-button").click()
|
|
self.driver.find_element_by_id("cpu_used").click()
|
|
self.driver.find_element_by_id("disk_io").click()
|
|
self.driver.find_element_by_id("recipe_version").click()
|
|
self.driver.find_element_by_id("time_taken").click()
|
|
self.driver.find_element_by_id("edit-columns-button").click()
|
|
# The operation is the same as case901
|
|
# dict: {lint text name : actual class name}
|
|
table_head_dict = {'Order':'order', 'Recipe':'recipe_name', 'Task':'task_name', 'Executed':'executed', \
|
|
'Outcome':'outcome', 'Cache attempt':'cache_attempt', 'Time (secs)':'time_taken', 'CPU usage':'cpu_used', \
|
|
'Disk I/O (ms)':'disk_io'}
|
|
for key in table_head_dict:
|
|
# This is tricky here: we are doing so because there may be more than 1
|
|
# same-name link_text in one page. So we only find element inside the table
|
|
self.find_element_by_link_text_in_table(self.table_name, key).click()
|
|
column_list = self.get_table_column_text("class", table_head_dict[key])
|
|
# after 1st click, the list should be either sequenced or inverted, but we don't have a "default order" here
|
|
# the point is, after another click, it should be another order
|
|
# the first case is special:this means every item in column_list is the same, so
|
|
# after one click, either sequenced or inverted will be fine
|
|
if (is_list_inverted(column_list) and is_list_sequenced(column_list)) \
|
|
or (not column_list) :
|
|
self.find_element_by_link_text_in_table(self.table_name, key).click()
|
|
column_list = self.get_table_column_text("class", table_head_dict[key])
|
|
self.assertTrue(is_list_sequenced(column_list) or is_list_inverted(column_list), \
|
|
msg=("%s column not in any order" % key))
|
|
elif is_list_inverted(column_list):
|
|
self.find_element_by_link_text_in_table(self.table_name, key).click()
|
|
column_list = self.get_table_column_text("class", table_head_dict[key])
|
|
self.assertTrue(is_list_sequenced(column_list), msg=("%s column not in order" % key))
|
|
else:
|
|
self.assertTrue(is_list_sequenced(column_list), msg=("%s column not in order" % key))
|
|
self.find_element_by_link_text_in_table(self.table_name, key).click()
|
|
column_list = self.get_table_column_text("class", table_head_dict[key])
|
|
self.assertTrue(is_list_inverted(column_list), msg=("%s column not inverted" % key))
|
|
# step 8-10
|
|
# filter dict: {link text name : filter table name in xpath}
|
|
filter_dict = {'Executed':'filter_executed', 'Outcome':'filter_outcome', 'Cache attempt':'filter_cache_attempt'}
|
|
for key in filter_dict:
|
|
temp_element = self.find_element_by_link_text_in_table(self.table_name, key)
|
|
# find the filter icon besides it.
|
|
# And here we must have break (1 sec) to get the popup stuff
|
|
temp_element.find_element_by_xpath("..//*[@class='icon-filter filtered']").click()
|
|
self.browser_delay()
|
|
avail_options = self.driver.find_elements_by_xpath("//*[@id='" + filter_dict[key] + "']//*[@name='filter'][not(@disabled)]")
|
|
for number in range(0, len(avail_options)):
|
|
avail_options[number].click()
|
|
self.browser_delay()
|
|
# click "Apply"
|
|
self.driver.find_element_by_xpath("//*[@id='" + filter_dict[key] + "']//*[@type='submit']").click()
|
|
# insert screen capture here
|
|
self.browser_delay()
|
|
self.save_screenshot(screenshot_type='selenium', append_name='step8')
|
|
# after the last option was clicked, we don't need operation below anymore
|
|
if number < len(avail_options)-1:
|
|
try:
|
|
temp_element = self.find_element_by_link_text_in_table(self.table_name, key)
|
|
temp_element.find_element_by_xpath("..//*[@class='icon-filter filtered']").click()
|
|
avail_options = self.driver.find_elements_by_xpath("//*[@id='" + filter_dict[key] + "']//*[@name='filter'][not(@disabled)]")
|
|
except:
|
|
print("in exception")
|
|
self.find_element_by_text("Show all tasks").click()
|
|
# self.driver.find_element_by_xpath("//*[@id='searchform']/button[2]").click()
|
|
temp_element = self.find_element_by_link_text_in_table(self.table_name, key)
|
|
temp_element.find_element_by_xpath("..//*[@class='icon-filter filtered']").click()
|
|
avail_options = self.driver.find_elements_by_xpath("//*[@id='" + filter_dict[key] + "']//*[@name='filter'][not(@disabled)]")
|
|
self.browser_delay()
|
|
# step 11
|
|
for item in ['order', 'task_name', 'executed', 'outcome', 'recipe_name', 'recipe_version']:
|
|
try:
|
|
self.find_element_by_xpath_in_table(self.table_name, "./tbody/tr[1]/*[@class='" + item + "']/a").click()
|
|
except NoSuchElementException as e:
|
|
# let it go...
|
|
print('no item in the colum' + item)
|
|
# insert screen shot here
|
|
self.save_screenshot(screenshot_type='selenium', append_name='step11')
|
|
self.driver.back()
|
|
# step 12-14
|
|
# about test_dict: please refer to testcase 904 requirement step 12-14
|
|
test_dict = {
|
|
'Time':{
|
|
'class':'time_taken',
|
|
'check_head_list':['Recipe', 'Task', 'Executed', 'Outcome', 'Time (secs)'],
|
|
'check_column_list':['cpu_used', 'cache_attempt', 'disk_io', 'order', 'recipe_version']
|
|
},
|
|
'CPU usage':{
|
|
'class':'cpu_used',
|
|
'check_head_list':['Recipe', 'Task', 'Executed', 'Outcome', 'CPU usage'],
|
|
'check_column_list':['cache_attempt', 'disk_io', 'order', 'recipe_version', 'time_taken']
|
|
},
|
|
'Disk I/O':{
|
|
'class':'disk_io',
|
|
'check_head_list':['Recipe', 'Task', 'Executed', 'Outcome', 'Disk I/O (ms)'],
|
|
'check_column_list':['cpu_used', 'cache_attempt', 'order', 'recipe_version', 'time_taken']
|
|
}
|
|
}
|
|
for key in test_dict:
|
|
self.find_element_by_partial_link_text_in_table('nav', 'core-image').click()
|
|
self.find_element_by_link_text_in_table('nav', key).click()
|
|
head_list = self.get_table_head_text('otable')
|
|
for item in test_dict[key]['check_head_list']:
|
|
self.assertTrue(item in head_list, msg=("%s not in head row" % item))
|
|
column_list = self.get_table_column_text('class', test_dict[key]['class'])
|
|
self.assertTrue(is_list_inverted(column_list), msg=("%s column not inverted" % key))
|
|
|
|
self.driver.find_element_by_id("edit-columns-button").click()
|
|
for item2 in test_dict[key]['check_column_list']:
|
|
self.driver.find_element_by_id(item2).click()
|
|
self.driver.find_element_by_id("edit-columns-button").click()
|
|
# TBD: save screen here
|
|
|
|
|
|
##############
|
|
# CASE 906 #
|
|
##############
|
|
def test_906(self):
|
|
self.case_no = self.get_case_number()
|
|
self.log.info(' CASE %s log: ' % str(self.case_no))
|
|
self.driver.maximize_window()
|
|
self.driver.get(self.base_url)
|
|
self.driver.find_element_by_link_text("core-image-minimal").click()
|
|
self.find_element_by_link_text_in_table('nav', 'Packages').click()
|
|
# find "bash" in first column (Packages)
|
|
self.driver.find_element_by_xpath("//*[@id='otable']//td[1]//*[text()='bash']").click()
|
|
# save sceen here to observe...
|
|
# step 6
|
|
self.driver.find_element_by_partial_link_text("Generated files").click()
|
|
head_list = self.get_table_head_text('otable')
|
|
for item in ['File', 'Size']:
|
|
self.assertTrue(item in head_list, msg=("%s not in head row" % item))
|
|
c_list = self.get_table_column_text('class', 'path')
|
|
self.assertTrue(is_list_sequenced(c_list), msg=("column not in order"))
|
|
# step 7
|
|
self.driver.find_element_by_partial_link_text("Runtime dependencies").click()
|
|
# save sceen here to observe...
|
|
# note that here table name is not 'otable'
|
|
head_list = self.get_table_head_text('dependencies')
|
|
for item in ['Package', 'Version', 'Size']:
|
|
self.assertTrue(item in head_list, msg=("%s not in head row" % item))
|
|
c_list = self.get_table_column_text_by_column_number('dependencies', 1)
|
|
self.assertTrue(is_list_sequenced(c_list), msg=("list not in order"))
|
|
texts = ['Size', 'License', 'Recipe', 'Recipe version', 'Layer', \
|
|
'Layer commit']
|
|
self.failUnless(self.is_text_present(texts))
|
|
|
|
|
|
##############
|
|
# CASE 910 #
|
|
##############
|
|
def test_910(self):
|
|
self.case_no = self.get_case_number()
|
|
self.log.info(' CASE %s log: ' % str(self.case_no))
|
|
image_type="core-image-minimal"
|
|
test_package1="busybox"
|
|
test_package2="lib"
|
|
self.driver.maximize_window()
|
|
self.driver.get(self.base_url)
|
|
self.driver.find_element_by_link_text(image_type).click()
|
|
self.driver.find_element_by_link_text("Recipes").click()
|
|
self.save_screenshot(screenshot_type='selenium', append_name='step3')
|
|
|
|
self.table_name = 'otable'
|
|
# This is how we find the "default" rows-number!
|
|
rows_displayed = int(Select(self.driver.find_element_by_css_selector("select.pagesize")).first_selected_option.text)
|
|
print(rows_displayed)
|
|
self.assertTrue(self.get_table_element(self.table_name, rows_displayed))
|
|
self.assertFalse(self.get_table_element(self.table_name, rows_displayed + 1))
|
|
|
|
# Check the default table is sorted by Recipe
|
|
tasks_column_count = len(self.driver.find_elements_by_xpath("/html/body/div[2]/div/div[2]/div[2]/table/tbody/tr/td[1]"))
|
|
print(tasks_column_count)
|
|
default_column_list = self.get_table_column_text_by_column_number(self.table_name, 1)
|
|
#print default_column_list
|
|
|
|
self.assertTrue(is_list_sequenced(default_column_list))
|
|
|
|
# Search text box background text is "Search recipes"
|
|
self.assertTrue(self.driver.find_element_by_xpath("//*[@id='searchform']/*[@placeholder='Search recipes']"))
|
|
|
|
self.driver.find_element_by_id("search").clear()
|
|
self.driver.find_element_by_id("search").send_keys(test_package1)
|
|
self.driver.find_element_by_id("search-button").click()
|
|
# Save screen here
|
|
self.save_screenshot(screenshot_type='selenium', append_name='step4')
|
|
self.driver.find_element_by_css_selector("i.icon-remove").click()
|
|
self.save_screenshot(screenshot_type='selenium', append_name='step4_2')
|
|
|
|
self.driver.find_element_by_id("edit-columns-button").click()
|
|
self.driver.find_element_by_id("depends_on").click()
|
|
self.driver.find_element_by_id("layer_version__branch").click()
|
|
self.driver.find_element_by_id("layer_version__layer__commit").click()
|
|
self.driver.find_element_by_id("depends_by").click()
|
|
self.driver.find_element_by_id("edit-columns-button").click()
|
|
|
|
self.find_element_by_link_text_in_table(self.table_name, 'Recipe').click()
|
|
# Check the inverted table by Recipe
|
|
# Recipe doesn't have class name
|
|
#inverted_tasks_column_count = len(self.driver.find_elements_by_xpath("/html/body/div[2]/div/div[2]/div[2]/table/tbody/tr/td[1]"))
|
|
#print inverted_tasks_column_count
|
|
#inverted_column_list = self.get_table_column_text_by_column_number(self.table_name, 1)
|
|
#print inverted_column_list
|
|
|
|
#self.driver.find_element_by_partial_link_text("zlib").click()
|
|
#self.driver.back()
|
|
#self.assertTrue(is_list_inverted(inverted_column_list))
|
|
#self.find_element_by_link_text_in_table(self.table_name, 'Recipe').click()
|
|
|
|
table_head_dict = {'Recipe':'recipe__name', 'Recipe file':'recipe_file', 'Section':'recipe_section', \
|
|
'License':'recipe_license', 'Layer':'layer_version__layer__name', \
|
|
'Layer branch':'layer_version__branch'}
|
|
for key in table_head_dict:
|
|
self.find_element_by_link_text_in_table(self.table_name, key).click()
|
|
column_list = self.get_table_column_text("class", table_head_dict[key])
|
|
if (is_list_inverted(column_list) and is_list_sequenced(column_list)) \
|
|
or (not column_list) :
|
|
self.find_element_by_link_text_in_table(self.table_name, key).click()
|
|
column_list = self.get_table_column_text("class", table_head_dict[key])
|
|
self.assertTrue(is_list_sequenced(column_list) or is_list_inverted(column_list))
|
|
self.driver.find_element_by_partial_link_text("acl").click()
|
|
self.driver.back()
|
|
self.assertTrue(is_list_sequenced(column_list) or is_list_inverted(column_list))
|
|
# Search text box background text is "Search recipes"
|
|
self.assertTrue(self.driver.find_element_by_xpath("//*[@id='searchform']/*[@placeholder='Search recipes']"))
|
|
self.driver.find_element_by_id("search").clear()
|
|
self.driver.find_element_by_id("search").send_keys(test_package2)
|
|
self.driver.find_element_by_id("search-button").click()
|
|
column_search_list = self.get_table_column_text("class", table_head_dict[key])
|
|
self.assertTrue(is_list_sequenced(column_search_list) or is_list_inverted(column_search_list))
|
|
self.driver.find_element_by_css_selector("i.icon-remove").click()
|
|
elif is_list_inverted(column_list):
|
|
self.find_element_by_link_text_in_table(self.table_name, key).click()
|
|
column_list = self.get_table_column_text("class", table_head_dict[key])
|
|
self.assertTrue(is_list_sequenced(column_list))
|
|
self.driver.find_element_by_partial_link_text("acl").click()
|
|
self.driver.back()
|
|
self.assertTrue(is_list_sequenced(column_list))
|
|
# Search text box background text is "Search recipes"
|
|
self.assertTrue(self.driver.find_element_by_xpath("//*[@id='searchform']/*[@placeholder='Search recipes']"))
|
|
self.driver.find_element_by_id("search").clear()
|
|
self.driver.find_element_by_id("search").send_keys(test_package2)
|
|
self.driver.find_element_by_id("search-button").click()
|
|
column_search_list = self.get_table_column_text("class", table_head_dict[key])
|
|
self.assertTrue(is_list_sequenced(column_search_list))
|
|
self.driver.find_element_by_css_selector("i.icon-remove").click()
|
|
else:
|
|
self.assertTrue(is_list_sequenced(column_list), msg=("list %s not sequenced" % key))
|
|
self.find_element_by_link_text_in_table(self.table_name, key).click()
|
|
column_list = self.get_table_column_text("class", table_head_dict[key])
|
|
self.assertTrue(is_list_inverted(column_list))
|
|
try:
|
|
self.driver.find_element_by_partial_link_text("acl").click()
|
|
except:
|
|
self.driver.find_element_by_partial_link_text("zlib").click()
|
|
self.driver.back()
|
|
self.assertTrue(is_list_inverted(column_list))
|
|
# Search text box background text is "Search recipes"
|
|
self.assertTrue(self.driver.find_element_by_xpath("//*[@id='searchform']/*[@placeholder='Search recipes']"))
|
|
self.driver.find_element_by_id("search").clear()
|
|
self.driver.find_element_by_id("search").send_keys(test_package2)
|
|
self.driver.find_element_by_id("search-button").click()
|
|
column_search_list = self.get_table_column_text("class", table_head_dict[key])
|
|
#print column_search_list
|
|
self.assertTrue(is_list_inverted(column_search_list))
|
|
self.driver.find_element_by_css_selector("i.icon-remove").click()
|
|
|
|
# Bug 5919
|
|
for key in table_head_dict:
|
|
print(key)
|
|
self.find_element_by_link_text_in_table(self.table_name, key).click()
|
|
self.driver.find_element_by_id("edit-columns-button").click()
|
|
self.driver.find_element_by_id(table_head_dict[key]).click()
|
|
self.driver.find_element_by_id("edit-columns-button").click()
|
|
self.browser_delay()
|
|
# After hide the column, the default table should be sorted by Recipe
|
|
tasks_column_count = len(self.driver.find_elements_by_partial_link_text("acl"))
|
|
#print tasks_column_count
|
|
default_column_list = self.get_table_column_text_by_column_number(self.table_name, 1)
|
|
#print default_column_list
|
|
self.assertTrue(is_list_sequenced(default_column_list))
|
|
|
|
self.driver.find_element_by_id("edit-columns-button").click()
|
|
self.driver.find_element_by_id("recipe_file").click()
|
|
self.driver.find_element_by_id("recipe_section").click()
|
|
self.driver.find_element_by_id("recipe_license").click()
|
|
self.driver.find_element_by_id("layer_version__layer__name").click()
|
|
self.driver.find_element_by_id("edit-columns-button").click()
|
|
|
|
|
|
##############
|
|
# CASE 911 #
|
|
##############
|
|
def test_911(self):
|
|
self.case_no = self.get_case_number()
|
|
self.log.info(' CASE %s log: ' % str(self.case_no))
|
|
self.driver.maximize_window()
|
|
self.driver.get(self.base_url)
|
|
self.driver.find_element_by_link_text("core-image-minimal").click()
|
|
self.find_element_by_link_text_in_table('nav', 'Recipes').click()
|
|
# step 3-5
|
|
self.driver.find_element_by_id("search").clear()
|
|
self.driver.find_element_by_id("search").send_keys("lib")
|
|
self.driver.find_element_by_id("search-button").click()
|
|
# save screen here for observation
|
|
self.save_screenshot(screenshot_type='selenium', append_name='step5')
|
|
# step 6
|
|
self.driver.find_element_by_css_selector("i.icon-remove").click()
|
|
self.driver.find_element_by_id("search").clear()
|
|
# we deliberately want "no result" here
|
|
self.driver.find_element_by_id("search").send_keys("no such input")
|
|
self.driver.find_element_by_id("search-button").click()
|
|
try:
|
|
self.find_element_by_text("Show all recipes").click()
|
|
except:
|
|
self.fail(msg='Could not identify blank page elements')
|
|
|
|
##############
|
|
# CASE 912 #
|
|
##############
|
|
def test_912(self):
|
|
self.case_no = self.get_case_number()
|
|
self.log.info(' CASE %s log: ' % str(self.case_no))
|
|
self.driver.maximize_window()
|
|
self.driver.get(self.base_url)
|
|
self.driver.find_element_by_link_text("core-image-minimal").click()
|
|
self.find_element_by_link_text_in_table('nav', 'Recipes').click()
|
|
# step 3
|
|
head_list = self.get_table_head_text('otable')
|
|
for item in ['Recipe', 'Recipe version', 'Recipe file', 'Section', 'License', 'Layer']:
|
|
self.assertTrue(item in head_list, msg=("item %s not in head row" % item))
|
|
self.driver.find_element_by_id("edit-columns-button").click()
|
|
self.driver.find_element_by_id("depends_on").click()
|
|
self.driver.find_element_by_id("layer_version__branch").click()
|
|
self.driver.find_element_by_id("layer_version__layer__commit").click()
|
|
self.driver.find_element_by_id("depends_by").click()
|
|
self.driver.find_element_by_id("edit-columns-button").click()
|
|
# check if columns selected above is shown
|
|
check_list = ['Dependencies', 'Layer branch', 'Layer commit', 'Reverse dependencies']
|
|
head_list = self.get_table_head_text('otable')
|
|
time.sleep(2)
|
|
print(head_list)
|
|
for item in check_list:
|
|
self.assertTrue(item in head_list, msg=("item %s not in head row" % item))
|
|
# un-check 'em all
|
|
self.driver.find_element_by_id("edit-columns-button").click()
|
|
self.driver.find_element_by_id("depends_on").click()
|
|
self.driver.find_element_by_id("layer_version__branch").click()
|
|
self.driver.find_element_by_id("layer_version__layer__commit").click()
|
|
self.driver.find_element_by_id("depends_by").click()
|
|
self.driver.find_element_by_id("edit-columns-button").click()
|
|
# don't exist any more
|
|
head_list = self.get_table_head_text('otable')
|
|
for item in check_list:
|
|
self.assertFalse(item in head_list, msg=("item %s should not be in head row" % item))
|
|
|
|
|
|
##############
|
|
# CASE 913 #
|
|
##############
|
|
def test_913(self):
|
|
self.case_no = self.get_case_number()
|
|
self.log.info(' CASE %s log: ' % str(self.case_no))
|
|
self.driver.maximize_window()
|
|
self.driver.get(self.base_url)
|
|
self.driver.find_element_by_link_text("core-image-minimal").click()
|
|
self.find_element_by_link_text_in_table('nav', 'Recipes').click()
|
|
# step 3
|
|
head_list = self.get_table_head_text('otable')
|
|
for item in ['Recipe', 'Recipe version', 'Recipe file', 'Section', 'License', 'Layer']:
|
|
self.assertTrue(item in head_list, msg=("item %s not in head row" % item))
|
|
# step 4
|
|
self.driver.find_element_by_id("edit-columns-button").click()
|
|
# save screen
|
|
self.browser_delay()
|
|
self.save_screenshot(screenshot_type='selenium', append_name='step4')
|
|
self.driver.find_element_by_id("edit-columns-button").click()
|
|
|
|
|
|
##############
|
|
# CASE 914 #
|
|
##############
|
|
def test_914(self):
|
|
self.case_no = self.get_case_number()
|
|
self.log.info(' CASE %s log: ' % str(self.case_no))
|
|
image_type="core-image-minimal"
|
|
test_package1="busybox"
|
|
test_package2="gdbm"
|
|
test_package3="gettext-native"
|
|
driver = self.driver
|
|
driver.maximize_window()
|
|
driver.get(self.base_url)
|
|
driver.find_element_by_link_text(image_type).click()
|
|
driver.find_element_by_link_text("Recipes").click()
|
|
driver.find_element_by_link_text(test_package1).click()
|
|
|
|
self.table_name = 'information'
|
|
|
|
tasks_row_count = len(driver.find_elements_by_xpath("//*[@id='"+self.table_name+"']/table/tbody/tr/td[1]"))
|
|
tasks_column_count = len(driver.find_elements_by_xpath("//*[@id='"+self.table_name+"']/table/tbody/tr[1]/td"))
|
|
print('rows: '+str(tasks_row_count))
|
|
print('columns: '+str(tasks_column_count))
|
|
|
|
Tasks_column = self.get_table_column_text_by_column_number(self.table_name, 2)
|
|
print ("Tasks_column=", Tasks_column)
|
|
|
|
key_tasks=["do_fetch", "do_unpack", "do_patch", "do_configure", "do_compile", "do_install", "do_package", "do_build"]
|
|
i = 0
|
|
while i < len(key_tasks):
|
|
if key_tasks[i] not in Tasks_column:
|
|
print ("Error! Missing key task: %s" % key_tasks[i])
|
|
else:
|
|
print ("%s is in tasks" % key_tasks[i])
|
|
i = i + 1
|
|
|
|
if Tasks_column.index(key_tasks[0]) != 0:
|
|
print ("Error! %s is not in the right position" % key_tasks[0])
|
|
else:
|
|
print ("%s is in right position" % key_tasks[0])
|
|
|
|
if Tasks_column[-1] != key_tasks[-1]:
|
|
print ("Error! %s is not in the right position" % key_tasks[-1])
|
|
else:
|
|
print ("%s is in right position" % key_tasks[-1])
|
|
|
|
driver.find_element_by_partial_link_text("Packages (").click()
|
|
packages_name = driver.find_element_by_partial_link_text("Packages (").text
|
|
print(packages_name)
|
|
packages_num = int(filter(str.isdigit, repr(packages_name)))
|
|
print(packages_num)
|
|
|
|
#switch the table to show more than 10 rows at a time
|
|
self.driver.find_element_by_xpath("//*[@id='packages-built']/div[1]/div/select").click()
|
|
Select(driver.find_element_by_xpath("//*[@id='packages-built']/div[1]/div/select")).select_by_value('150')
|
|
self.driver.find_element_by_xpath("//*[@id='packages-built']/div[1]/div/select").send_keys(Keys.ENTER)
|
|
|
|
packages_row_count = len(driver.find_elements_by_xpath("//*[@id='otable']/tbody/tr/td[1]"))
|
|
print(packages_row_count)
|
|
|
|
if packages_num != packages_row_count:
|
|
print ("Error! The packages number is not correct")
|
|
else:
|
|
print ("The packages number is correct")
|
|
|
|
driver.find_element_by_partial_link_text("Build dependencies (").click()
|
|
depends_name = driver.find_element_by_partial_link_text("Build dependencies (").text
|
|
print(depends_name)
|
|
depends_num = int(list(filter(str.isdigit, repr(depends_name))))
|
|
print(depends_num)
|
|
|
|
if depends_num == 0:
|
|
depends_message = repr(driver.find_element_by_css_selector("div.alert.alert-info").text)
|
|
print(depends_message)
|
|
if depends_message.find("has no build dependencies.") < 0:
|
|
print ("Error! The message isn't expected.")
|
|
else:
|
|
print ("The message is expected")
|
|
else:
|
|
depends_row_count = len(driver.find_elements_by_xpath("//*[@id='dependencies']/table/tbody/tr/td[1]"))
|
|
print(depends_row_count)
|
|
if depends_num != depends_row_count:
|
|
print ("Error! The dependent packages number is not correct")
|
|
else:
|
|
print ("The dependent packages number is correct")
|
|
|
|
driver.find_element_by_partial_link_text("Reverse build dependencies (").click()
|
|
rdepends_name = driver.find_element_by_partial_link_text("Reverse build dependencies (").text
|
|
print(rdepends_name)
|
|
rdepends_num = int(filter(str.isdigit, repr(rdepends_name)))
|
|
print(rdepends_num)
|
|
|
|
if rdepends_num == 0:
|
|
rdepends_message = repr(driver.find_element_by_css_selector("#brought-in-by > div.alert.alert-info").text)
|
|
print(rdepends_message)
|
|
if rdepends_message.find("has no reverse build dependencies.") < 0:
|
|
print ("Error! The message isn't expected.")
|
|
else:
|
|
print ("The message is expected")
|
|
else:
|
|
print ("The reverse dependent packages number is correct")
|
|
|
|
driver.find_element_by_link_text("Recipes").click()
|
|
driver.find_element_by_link_text(test_package2).click()
|
|
driver.find_element_by_partial_link_text("Packages (").click()
|
|
driver.find_element_by_partial_link_text("Build dependencies (").click()
|
|
driver.find_element_by_partial_link_text("Reverse build dependencies (").click()
|
|
|
|
|
|
driver.find_element_by_link_text("Recipes").click()
|
|
driver.find_element_by_link_text(test_package3).click()
|
|
|
|
native_tasks_row_count = len(driver.find_elements_by_xpath("//*[@id='information']/table/tbody/tr/td[1]"))
|
|
native_tasks_column_count = len(driver.find_elements_by_xpath("//*[@id='information']/table/tbody/tr[1]/td"))
|
|
print(native_tasks_row_count)
|
|
print(native_tasks_column_count)
|
|
|
|
Native_Tasks_column = self.get_table_column_text_by_column_number(self.table_name, 2)
|
|
print ("Native_Tasks_column=", Native_Tasks_column)
|
|
|
|
native_key_tasks=["do_fetch", "do_unpack", "do_patch", "do_configure", "do_compile", "do_install", "do_build"]
|
|
i = 0
|
|
while i < len(native_key_tasks):
|
|
if native_key_tasks[i] not in Native_Tasks_column:
|
|
print ("Error! Missing key task: %s" % native_key_tasks[i])
|
|
else:
|
|
print ("%s is in tasks" % native_key_tasks[i])
|
|
i = i + 1
|
|
|
|
if Native_Tasks_column.index(native_key_tasks[0]) != 0:
|
|
print ("Error! %s is not in the right position" % native_key_tasks[0])
|
|
else:
|
|
print ("%s is in right position" % native_key_tasks[0])
|
|
|
|
if Native_Tasks_column[-1] != native_key_tasks[-1]:
|
|
print ("Error! %s is not in the right position" % native_key_tasks[-1])
|
|
else:
|
|
print ("%s is in right position" % native_key_tasks[-1])
|
|
|
|
driver.find_element_by_partial_link_text("Packages (").click()
|
|
native_packages_name = driver.find_element_by_partial_link_text("Packages (").text
|
|
print(native_packages_name)
|
|
native_packages_num = int(filter(str.isdigit, repr(native_packages_name)))
|
|
print(native_packages_num)
|
|
|
|
if native_packages_num != 0:
|
|
print ("Error! Native task shouldn't have any packages.")
|
|
else:
|
|
native_package_message = repr(driver.find_element_by_css_selector("#packages-built > div.alert.alert-info").text)
|
|
print(native_package_message)
|
|
if native_package_message.find("does not build any packages.") < 0:
|
|
print ("Error! The message for native task isn't expected.")
|
|
else:
|
|
print ("The message for native task is expected.")
|
|
|
|
driver.find_element_by_partial_link_text("Build dependencies (").click()
|
|
native_depends_name = driver.find_element_by_partial_link_text("Build dependencies (").text
|
|
print(native_depends_name)
|
|
native_depends_num = int(filter(str.isdigit, repr(native_depends_name)))
|
|
print(native_depends_num)
|
|
|
|
native_depends_row_count = len(driver.find_elements_by_xpath("//*[@id='dependencies']/table/tbody/tr/td[1]"))
|
|
print(native_depends_row_count)
|
|
|
|
if native_depends_num != native_depends_row_count:
|
|
print ("Error! The dependent packages number is not correct")
|
|
else:
|
|
print ("The dependent packages number is correct")
|
|
|
|
driver.find_element_by_partial_link_text("Reverse build dependencies (").click()
|
|
native_rdepends_name = driver.find_element_by_partial_link_text("Reverse build dependencies (").text
|
|
print(native_rdepends_name)
|
|
native_rdepends_num = int(filter(str.isdigit, repr(native_rdepends_name)))
|
|
print(native_rdepends_num)
|
|
|
|
native_rdepends_row_count = len(driver.find_elements_by_xpath("//*[@id='brought-in-by']/table/tbody/tr/td[1]"))
|
|
print(native_rdepends_row_count)
|
|
|
|
if native_rdepends_num != native_rdepends_row_count:
|
|
print ("Error! The reverse dependent packages number is not correct")
|
|
else:
|
|
print ("The reverse dependent packages number is correct")
|
|
|
|
driver.find_element_by_link_text("Recipes").click()
|
|
|
|
|
|
##############
|
|
# CASE 915 #
|
|
##############
|
|
def test_915(self):
|
|
self.case_no = self.get_case_number()
|
|
self.log.info(' CASE %s log: ' % str(self.case_no))
|
|
self.driver.maximize_window()
|
|
self.driver.get(self.base_url)
|
|
self.driver.find_element_by_link_text("core-image-minimal").click()
|
|
# step 3
|
|
self.find_element_by_link_text_in_table('nav', 'Configuration').click()
|
|
self.driver.find_element_by_link_text("BitBake variables").click()
|
|
# step 4
|
|
self.driver.find_element_by_id("search").clear()
|
|
self.driver.find_element_by_id("search").send_keys("lib")
|
|
self.driver.find_element_by_id("search-button").click()
|
|
# save screen to see result
|
|
self.browser_delay()
|
|
self.save_screenshot(screenshot_type='selenium', append_name='step4')
|
|
# step 5
|
|
self.driver.find_element_by_css_selector("i.icon-remove").click()
|
|
head_list = self.get_table_head_text('otable')
|
|
print(head_list)
|
|
print(len(head_list))
|
|
self.assertTrue(head_list == ['Variable', 'Value', 'Set in file', 'Description'], \
|
|
msg=("head row contents wrong"))
|
|
# step 8
|
|
# search other string. and click "Variable" to re-sort, check if table
|
|
# head is still the same
|
|
self.driver.find_element_by_id("search").clear()
|
|
self.driver.find_element_by_id("search").send_keys("poky")
|
|
self.driver.find_element_by_id("search-button").click()
|
|
self.find_element_by_link_text_in_table('otable', 'Variable').click()
|
|
head_list = self.get_table_head_text('otable')
|
|
self.assertTrue(head_list == ['Variable', 'Value', 'Set in file', 'Description'], \
|
|
msg=("head row contents wrong"))
|
|
self.find_element_by_link_text_in_table('otable', 'Variable').click()
|
|
head_list = self.get_table_head_text('otable')
|
|
self.assertTrue(head_list == ['Variable', 'Value', 'Set in file', 'Description'], \
|
|
msg=("head row contents wrong"))
|
|
|
|
|
|
##############
|
|
# CASE 916 #
|
|
##############
|
|
def test_916(self):
|
|
self.case_no = self.get_case_number()
|
|
self.log.info(' CASE %s log: ' % str(self.case_no))
|
|
self.driver.maximize_window()
|
|
self.driver.get(self.base_url)
|
|
self.driver.find_element_by_link_text("core-image-minimal").click()
|
|
# step 2-3
|
|
self.find_element_by_link_text_in_table('nav', 'Configuration').click()
|
|
self.driver.find_element_by_link_text("BitBake variables").click()
|
|
variable_list = self.get_table_column_text('class', 'variable_name')
|
|
self.assertTrue(is_list_sequenced(variable_list), msg=("list not in order"))
|
|
# step 4
|
|
self.find_element_by_link_text_in_table('otable', 'Variable').click()
|
|
variable_list = self.get_table_column_text('class', 'variable_name')
|
|
self.assertTrue(is_list_inverted(variable_list), msg=("list not inverted"))
|
|
self.find_element_by_link_text_in_table('otable', 'Variable').click()
|
|
# step 5
|
|
# searching won't change the sequentiality
|
|
self.driver.find_element_by_id("search").clear()
|
|
self.driver.find_element_by_id("search").send_keys("lib")
|
|
self.driver.find_element_by_id("search-button").click()
|
|
variable_list = self.get_table_column_text('class', 'variable_name')
|
|
self.assertTrue(is_list_sequenced(variable_list), msg=("list not in order"))
|
|
|
|
|
|
##############
|
|
# CASE 923 #
|
|
##############
|
|
def test_923(self):
|
|
self.case_no = self.get_case_number()
|
|
self.log.info(' CASE %s log: ' % str(self.case_no))
|
|
self.driver.maximize_window()
|
|
self.driver.get(self.base_url)
|
|
# Step 2
|
|
# default sequence in "Completed on" column is inverted
|
|
c_list = self.get_table_column_text('class', 'completed_on')
|
|
self.assertTrue(is_list_inverted(c_list), msg=("list not inverted"))
|
|
# step 3
|
|
self.driver.find_element_by_id("edit-columns-button").click()
|
|
self.driver.find_element_by_id("started_on").click()
|
|
self.driver.find_element_by_id("time").click()
|
|
self.driver.find_element_by_id("edit-columns-button").click()
|
|
head_list = self.get_table_head_text('otable')
|
|
for item in ['Outcome', 'Recipe', 'Machine', 'Started on', 'Completed on', 'Failed tasks', 'Errors', 'Warnings', 'Time', "Image files", "Project"]:
|
|
self.failUnless(item in head_list, msg=item+' is missing from table head.')
|
|
|
|
|
|
##############
|
|
# CASE 924 #
|
|
##############
|
|
def test_924(self):
|
|
self.case_no = self.get_case_number()
|
|
self.log.info(' CASE %s log: ' % str(self.case_no))
|
|
self.driver.maximize_window()
|
|
self.driver.get(self.base_url)
|
|
# Please refer to case 924 requirement
|
|
# default sequence in "Completed on" column is inverted
|
|
c_list = self.get_table_column_text('class', 'completed_on')
|
|
self.assertTrue(is_list_inverted(c_list), msg=("list not inverted"))
|
|
# Step 4
|
|
# click Errors , order in "Completed on" should be disturbed. Then hide
|
|
# error column to check if order in "Completed on" can be restored
|
|
#THIS TEST IS NO LONGER VALID DUE TO DESIGN CHANGES. LEAVING IN PENDING UPDATES TO DESIGN
|
|
#self.find_element_by_link_text_in_table('otable', 'Errors').click()
|
|
#self.driver.find_element_by_id("edit-columns-button").click()
|
|
#self.driver.find_element_by_id("errors_no").click()
|
|
#self.driver.find_element_by_id("edit-columns-button").click()
|
|
# Note: without time.sleep here, there'll be unpredictable error..TBD
|
|
time.sleep(1)
|
|
c_list = self.get_table_column_text('class', 'completed_on')
|
|
self.assertTrue(is_list_inverted(c_list), msg=("list not inverted"))
|
|
|
|
|
|
##############
|
|
# CASE 940 #
|
|
##############
|
|
def test_940(self):
|
|
self.case_no = self.get_case_number()
|
|
self.log.info(' CASE %s log: ' % str(self.case_no))
|
|
self.driver.maximize_window()
|
|
self.driver.get(self.base_url)
|
|
self.driver.find_element_by_link_text("core-image-minimal").click()
|
|
# Step 2-3
|
|
self.find_element_by_link_text_in_table('nav', 'Packages').click()
|
|
check_head_list = ['Package', 'Package version', 'Size', 'Recipe']
|
|
head_list = self.get_table_head_text('otable')
|
|
self.assertTrue(head_list == check_head_list, msg=("head row not as expected"))
|
|
# Step 4
|
|
# pulldown menu
|
|
option_ids = ['recipe__layer_version__layer__name', 'recipe__layer_version__branch', \
|
|
'recipe__layer_version__layer__commit', 'license', 'recipe__version']
|
|
self.driver.find_element_by_id("edit-columns-button").click()
|
|
for item in option_ids:
|
|
if not self.driver.find_element_by_id(item).is_selected():
|
|
self.driver.find_element_by_id(item).click()
|
|
self.driver.find_element_by_id("edit-columns-button").click()
|
|
# save screen here to observe that 'Package' and 'Package version' is
|
|
# not selectable
|
|
self.browser_delay()
|
|
self.save_screenshot(screenshot_type='selenium', append_name='step4')
|
|
|
|
|
|
##############
|
|
# CASE 941 #
|
|
##############
|
|
def test_941(self):
|
|
self.case_no = self.get_case_number()
|
|
self.log.info(' CASE %s log: ' % str(self.case_no))
|
|
self.driver.maximize_window()
|
|
self.driver.get(self.base_url)
|
|
self.driver.find_element_by_link_text("core-image-minimal").click()
|
|
# Step 2-3
|
|
self.find_element_by_link_text_in_table('nav', 'Packages').click()
|
|
# column -- Package
|
|
column_list = self.get_table_column_text_by_column_number('otable', 1)
|
|
self.assertTrue(is_list_sequenced(column_list), msg=("list not in order"))
|
|
self.find_element_by_link_text_in_table('otable', 'Size').click()
|
|
|
|
|
|
##############
|
|
# CASE 942 #
|
|
##############
|
|
def test_942(self):
|
|
self.case_no = self.get_case_number()
|
|
self.log.info(' CASE %s log: ' % str(self.case_no))
|
|
self.driver.maximize_window()
|
|
self.driver.get(self.base_url)
|
|
self.driver.find_element_by_link_text("core-image-minimal").click()
|
|
self.driver.find_element_by_link_text("Packages").click()
|
|
#get initial table header
|
|
head_list = self.get_table_head_text('otable')
|
|
#remove the Recipe column from table header
|
|
self.driver.find_element_by_id("edit-columns-button").click()
|
|
self.driver.find_element_by_id("recipe__name").click()
|
|
self.driver.find_element_by_id("edit-columns-button").click()
|
|
#get modified table header
|
|
new_head = self.get_table_head_text('otable')
|
|
self.assertTrue(head_list > new_head)
|
|
|
|
##############
|
|
# CASE 943 #
|
|
##############
|
|
def test_943(self):
|
|
self.case_no = self.get_case_number()
|
|
self.log.info(' CASE %s log: ' % str(self.case_no))
|
|
self.driver.maximize_window()
|
|
self.driver.get(self.base_url)
|
|
self.driver.find_element_by_link_text("core-image-minimal").click()
|
|
self.driver.find_element_by_link_text("Packages").click()
|
|
#search for the "bash" package -> this should definitely be present
|
|
self.driver.find_element_by_id("search").clear()
|
|
self.driver.find_element_by_id("search").send_keys("bash")
|
|
self.driver.find_element_by_id("search-button").click()
|
|
#check for the search result message "XX packages found"
|
|
self.assertTrue(self.is_text_present("packages found"), msg=("no packages found text"))
|
|
|
|
|
|
##############
|
|
# CASE 944 #
|
|
##############
|
|
def test_944(self):
|
|
self.case_no = self.get_case_number()
|
|
self.log.info(' CASE %s log: ' % str(self.case_no))
|
|
self.driver.maximize_window()
|
|
self.driver.get(self.base_url)
|
|
self.driver.find_element_by_link_text("core-image-minimal").click()
|
|
# step 1: test Recipes page stuff
|
|
self.driver.find_element_by_link_text("Recipes").click()
|
|
# for these 3 items, default status is not-checked
|
|
self.driver.find_element_by_id("edit-columns-button").click()
|
|
self.driver.find_element_by_id("layer_version__branch").click()
|
|
self.driver.find_element_by_id("layer_version__layer__commit").click()
|
|
self.driver.find_element_by_id("edit-columns-button").click()
|
|
# otable is the recipes table here
|
|
otable_head_text = self.get_table_head_text('otable')
|
|
for item in ["Layer", "Layer branch", "Layer commit"]:
|
|
self.failIf(item not in otable_head_text, msg=item+' not in table head.')
|
|
# click the fist recipe, whatever it is
|
|
self.get_table_element("otable", 1, 1).click()
|
|
self.assertTrue(self.is_text_present(["Layer", "Layer branch", "Layer commit", "Recipe file"]), \
|
|
msg=("text not in web page"))
|
|
|
|
# step 2: test Packages page stuff. almost same as above
|
|
self.driver.back()
|
|
self.browser_delay()
|
|
self.driver.find_element_by_link_text("Packages").click()
|
|
self.driver.find_element_by_id("edit-columns-button").click()
|
|
self.driver.find_element_by_id("recipe__layer_version__layer__name").click()
|
|
self.driver.find_element_by_id("recipe__layer_version__branch").click()
|
|
self.driver.find_element_by_id("recipe__layer_version__layer__commit").click()
|
|
self.driver.find_element_by_id("edit-columns-button").click()
|
|
otable_head_text = self.get_table_head_text("otable")
|
|
for item in ["Layer", "Layer branch", "Layer commit"]:
|
|
self.assertFalse(item not in otable_head_text, msg=("item %s should be in head row" % item))
|
|
# click the fist recipe, whatever it is
|
|
self.get_table_element("otable", 1, 1).click()
|
|
self.assertTrue(self.is_text_present(["Layer", "Layer branch", "Layer commit"]), \
|
|
msg=("text not in web page"))
|
|
|
|
# step 3: test Packages core-image-minimal(images) stuff. almost same as above. Note when future element-id changes...
|
|
self.driver.back()
|
|
self.driver.find_element_by_link_text("core-image-minimal").click()
|
|
self.driver.find_element_by_id("edit-columns-button").click()
|
|
self.driver.find_element_by_id("layer_name").click()
|
|
self.driver.find_element_by_id("layer_branch").click()
|
|
self.driver.find_element_by_id("layer_commit").click()
|
|
self.driver.find_element_by_id("edit-columns-button").click()
|
|
otable_head_text = self.get_table_head_text("otable")
|
|
for item in ["Layer", "Layer branch", "Layer commit"]:
|
|
self.assertFalse(item not in otable_head_text, msg=("item %s should be in head row" % item))
|
|
# click the fist recipe, whatever it is
|
|
self.get_table_element("otable", 1, 1).click()
|
|
self.assertTrue(self.is_text_present(["Layer", "Layer branch", "Layer commit"]), \
|
|
msg=("text not in web page"))
|
|
|
|
# step 4: check Configuration page
|
|
self.driver.back()
|
|
self.driver.find_element_by_link_text("Configuration").click()
|
|
otable_head_text = self.get_table_head_text()
|
|
self.assertTrue(self.is_text_present(["Layer", "Layer branch", "Layer commit"]), \
|
|
msg=("text not in web page"))
|
|
|
|
|
|
##############
|
|
# CASE 945 #
|
|
##############
|
|
def test_945(self):
|
|
self.case_no = self.get_case_number()
|
|
self.log.info(' CASE %s log: ' % str(self.case_no))
|
|
self.driver.maximize_window()
|
|
for item in ["Packages", "Recipes", "Tasks"]:
|
|
self.driver.get(self.base_url)
|
|
self.driver.find_element_by_link_text("core-image-minimal").click()
|
|
self.driver.find_element_by_link_text(items).click()
|
|
|
|
# this may be page specific. If future page content changes, try to replace it with new xpath
|
|
xpath_showrows = "/html/body/div[4]/div/div/div[2]/div[2]/div[2]/div/div/div[2]/select"
|
|
xpath_table = "html/body/div[4]/div/div/div[2]/div[2]/table/tbody"#"id=('otable')/tbody"
|
|
self.driver.find_element_by_xpath(xpath_showrows).click()
|
|
rows_displayed = int(self.driver.find_element_by_xpath(xpath_showrows + "/option[2]").text)
|
|
|
|
# not sure if this is a Selenium Select bug: If page is not refreshed here, "select(by visible text)" operation will go back to 100-row page
|
|
# Sure we can use driver.get(url) to refresh page, but since page will vary, we use click link text here
|
|
self.driver.find_element_by_link_text(items).click()
|
|
Select(self.driver.find_element_by_css_selector("select.pagesize")).select_by_visible_text(str(rows_displayed))
|
|
self.failUnless(self.is_element_present(By.XPATH, xpath_table + "/tr[" + str(rows_displayed) +"]"))
|
|
self.failIf(self.is_element_present(By.XPATH, xpath_table + "/tr[" + str(rows_displayed+1) +"]"))
|
|
|
|
# click 1st package, then go back to check if it's still those rows shown.
|
|
self.driver.find_element_by_xpath(xpath_otable + "/tr[1]/td[1]/a").click()
|
|
time.sleep(3)
|
|
self.driver.find_element_by_link_text(item).click()
|
|
self.assertTrue(self.is_element_present(By.XPATH, xpath_otable + "/tr[" + str(option_tobeselected) +"]"),\
|
|
msg=("Row %d should exist" %option_tobeselected))
|
|
self.assertFalse(self.is_element_present(By.XPATH, xpath_otable + "/tr[" + str(option_tobeselected+1) +"]"),\
|
|
msg=("Row %d should not exist" %(option_tobeselected+1)))
|
|
|
|
|
|
|
|
##############
|
|
# CASE 946 #
|
|
##############
|
|
def test_946(self):
|
|
self.case_no = self.get_case_number()
|
|
self.log.info(' CASE %s log: ' % str(self.case_no))
|
|
self.driver.maximize_window()
|
|
self.driver.get(self.base_url)
|
|
self.driver.find_element_by_link_text("core-image-minimal").click()
|
|
self.driver.find_element_by_link_text("Configuration").click()
|
|
# step 3-4
|
|
check_list = ["Summary", "BitBake variables"]
|
|
for item in check_list:
|
|
if not self.is_element_present(how=By.LINK_TEXT, what=item):
|
|
self.log.error("%s not found" %item)
|
|
if not self.is_text_present(['Layers', 'Layer', 'Layer branch', 'Layer commit']):
|
|
self.log.error("text not found")
|
|
# step 5
|
|
self.driver.find_element_by_link_text("BitBake variables").click()
|
|
if not self.is_text_present(['Variable', 'Value', 'Set in file', 'Description']):
|
|
self.log.error("text not found")
|
|
# This may be unstable because it's page-specific
|
|
# step 6: this is how we find filter beside "Set in file"
|
|
temp_element = self.find_element_by_text_in_table('otable', "Set in file")
|
|
temp_element.find_element_by_xpath("..//*/a/i[@class='icon-filter filtered']").click()
|
|
self.browser_delay()
|
|
self.driver.find_element_by_xpath("(//input[@name='filter'])[3]").click()
|
|
btns = self.driver.find_elements_by_css_selector("button.btn.btn-primary")
|
|
for btn in btns:
|
|
try:
|
|
btn.click()
|
|
break
|
|
except:
|
|
pass
|
|
# save screen here
|
|
self.browser_delay()
|
|
self.save_screenshot(screenshot_type='selenium', append_name='step6')
|
|
self.driver.find_element_by_id("edit-columns-button").click()
|
|
# save screen here
|
|
# step 7
|
|
# we should manually check the step 6-8 result using screenshot
|
|
self.browser_delay()
|
|
self.save_screenshot(screenshot_type='selenium', append_name='step7')
|
|
self.driver.find_element_by_id("edit-columns-button").click()
|
|
# step 9
|
|
# click the 1st item, no matter what it is
|
|
self.driver.find_element_by_xpath("//*[@id='otable']/tbody/tr[1]/td[1]/a").click()
|
|
# give it 1 sec so the pop-up becomes the "active_element"
|
|
time.sleep(1)
|
|
element = self.driver.switch_to.active_element
|
|
check_list = ['Order', 'Configuration file', 'Operation', 'Line number']
|
|
for item in check_list:
|
|
if item not in element.text:
|
|
self.log.error("%s not found" %item)
|
|
# any better way to close this pop-up? ... TBD
|
|
element.find_element_by_class_name("close").click()
|
|
# step 10 : need to manually check "Yocto Manual" in saved screen
|
|
self.driver.find_element_by_css_selector("i.icon-share.get-info").click()
|
|
# save screen here
|
|
time.sleep(5)
|
|
self.save_screenshot(screenshot_type='native', append_name='step10')
|
|
|
|
|
|
##############
|
|
# CASE 947 #
|
|
##############
|
|
def test_947(self):
|
|
self.case_no = self.get_case_number()
|
|
self.log.info(' CASE %s log: ' % str(self.case_no))
|
|
self.driver.maximize_window()
|
|
self.driver.get(self.base_url)
|
|
self.driver.find_element_by_link_text("core-image-minimal").click()
|
|
self.find_element_by_link_text_in_table('nav', 'Configuration').click()
|
|
# step 2
|
|
self.driver.find_element_by_link_text("BitBake variables").click()
|
|
# step 3
|
|
def xpath_option(column_name):
|
|
# return xpath of options under "Edit columns" button
|
|
return self.shortest_xpath('id', 'navTab') + self.shortest_xpath('id', 'editcol') \
|
|
+ self.shortest_xpath('id', column_name)
|
|
self.driver.find_element_by_id('edit-columns-button').click()
|
|
# by default, option "Description" and "Set in file" were checked
|
|
self.driver.find_element_by_xpath(xpath_option('description')).click()
|
|
self.driver.find_element_by_xpath(xpath_option('file')).click()
|
|
self.driver.find_element_by_id('edit-columns-button').click()
|
|
check_list = ['Description', 'Set in file']
|
|
head_list = self.get_table_head_text('otable')
|
|
for item in check_list:
|
|
self.assertFalse(item in head_list, msg=("item %s should not be in head row" % item))
|
|
# check these 2 options and verify again
|
|
self.driver.find_element_by_id('edit-columns-button').click()
|
|
self.driver.find_element_by_xpath(xpath_option('description')).click()
|
|
self.driver.find_element_by_xpath(xpath_option('file')).click()
|
|
self.driver.find_element_by_id('edit-columns-button').click()
|
|
head_list = self.get_table_head_text('otable')
|
|
for item in check_list:
|
|
self.assertTrue(item in head_list, msg=("item %s not in head row" % item))
|
|
|
|
|
|
##############
|
|
# CASE 948 #
|
|
##############
|
|
def test_948(self):
|
|
self.case_no = self.get_case_number()
|
|
self.log.info(' CASE %s log: ' % str(self.case_no))
|
|
self.driver.maximize_window()
|
|
self.driver.get(self.base_url)
|
|
self.driver.find_element_by_link_text("core-image-minimal").click()
|
|
self.find_element_by_link_text_in_table('nav', 'Configuration').click()
|
|
self.driver.find_element_by_link_text("BitBake variables").click()
|
|
#get number of variables visible by default
|
|
number_before_search = self.driver.find_element_by_class_name('page-header').text
|
|
# search for a while...
|
|
self.driver.find_element_by_id("search").clear()
|
|
self.driver.find_element_by_id("search").send_keys("BB")
|
|
self.driver.find_element_by_id("search-button").click()
|
|
#get number of variables visible after search
|
|
number_after_search = self.driver.find_element_by_class_name('page-header').text
|
|
self.assertTrue(number_before_search > number_after_search, msg=("items should be less after search"))
|
|
|
|
|
|
##############
|
|
# CASE 949 #
|
|
##############
|
|
def test_949(self):
|
|
self.case_no = self.get_case_number()
|
|
self.log.info(' CASE %s log: ' % str(self.case_no))
|
|
self.driver.maximize_window()
|
|
self.driver.get(self.base_url)
|
|
self.driver.find_element_by_link_text("core-image-minimal").click()
|
|
self.find_element_by_link_text_in_table('nav', 'core-image-minimal').click()
|
|
# step 3
|
|
try:
|
|
self.driver.find_element_by_partial_link_text("Packages included")
|
|
self.driver.find_element_by_partial_link_text("Directory structure")
|
|
except Exception as e:
|
|
self.log.error(e)
|
|
self.assertFalse(True)
|
|
# step 4
|
|
head_list = self.get_table_head_text('otable')
|
|
for item in ['Package', 'Package version', 'Size', 'Dependencies', 'Reverse dependencies', 'Recipe']:
|
|
self.assertTrue(item in head_list, msg=("item %s not in head row" % item))
|
|
# step 5-6
|
|
self.driver.find_element_by_id("edit-columns-button").click()
|
|
selectable_class = 'checkbox'
|
|
# minimum-table : means unselectable items
|
|
unselectable_class = 'checkbox muted'
|
|
selectable_check_list = ['Dependencies', 'Layer', 'Layer branch', 'Layer commit', \
|
|
'License', 'Recipe', 'Recipe version', 'Reverse dependencies', \
|
|
'Size', 'Size over total (%)']
|
|
unselectable_check_list = ['Package', 'Package version']
|
|
selectable_list = list()
|
|
unselectable_list = list()
|
|
selectable_elements = self.driver.find_elements_by_xpath("//*[@id='editcol']//*[@class='" + selectable_class + "']")
|
|
unselectable_elements = self.driver.find_elements_by_xpath("//*[@id='editcol']//*[@class='" + unselectable_class + "']")
|
|
for element in selectable_elements:
|
|
selectable_list.append(element.text)
|
|
for element in unselectable_elements:
|
|
unselectable_list.append(element.text)
|
|
# check them
|
|
for item in selectable_check_list:
|
|
self.assertTrue(item in selectable_list, msg=("%s not found in dropdown menu" % item))
|
|
for item in unselectable_check_list:
|
|
self.assertTrue(item in unselectable_list, msg=("%s not found in dropdown menu" % item))
|
|
self.driver.find_element_by_id("edit-columns-button").click()
|
|
# step 7
|
|
self.driver.find_element_by_partial_link_text("Directory structure").click()
|
|
head_list = self.get_table_head_text('dirtable')
|
|
for item in ['Directory / File', 'Symbolic link to', 'Source package', 'Size', 'Permissions', 'Owner', 'Group']:
|
|
self.assertTrue(item in head_list, msg=("%s not found in Directory structure table head" % item))
|
|
|
|
##############
|
|
# CASE 950 #
|
|
##############
|
|
def test_950(self):
|
|
self.case_no = self.get_case_number()
|
|
self.log.info(' CASE %s log: ' % str(self.case_no))
|
|
self.driver.maximize_window()
|
|
self.driver.get(self.base_url)
|
|
# step3&4: so far we're not sure if there's "successful build" or "failed
|
|
# build".If either of them doesn't exist, we can still go on other steps
|
|
check_list = ['Configuration', 'Tasks', 'Recipes', 'Packages', 'Time', 'CPU usage', 'Disk I/O']
|
|
has_successful_build = 1
|
|
has_failed_build = 1
|
|
try:
|
|
pass_icon = self.driver.find_element_by_xpath("//*[@class='icon-ok-sign success']")
|
|
except Exception:
|
|
self.log.info("no successful build exists")
|
|
has_successful_build = 0
|
|
pass
|
|
if has_successful_build:
|
|
pass_icon.click()
|
|
# save screen here to check if it matches requirement.
|
|
self.browser_delay()
|
|
self.save_screenshot(screenshot_type='selenium', append_name='step3_1')
|
|
for item in check_list:
|
|
try:
|
|
self.find_element_by_link_text_in_table('nav', item)
|
|
except Exception:
|
|
self.assertFalse(True, msg=("link %s cannot be found in the page" % item))
|
|
# step 6
|
|
check_list_2 = ['Packages included', 'Total package size', \
|
|
'License manifest', 'Image files']
|
|
self.assertTrue(self.is_text_present(check_list_2), msg=("text not in web page"))
|
|
self.driver.back()
|
|
try:
|
|
fail_icon = self.driver.find_element_by_xpath("//*[@class='icon-minus-sign error']")
|
|
except Exception:
|
|
has_failed_build = 0
|
|
self.log.info("no failed build exists")
|
|
pass
|
|
if has_failed_build:
|
|
fail_icon.click()
|
|
# save screen here to check if it matches requirement.
|
|
self.browser_delay()
|
|
self.save_screenshot(screenshot_type='selenium', append_name='step3_2')
|
|
for item in check_list:
|
|
try:
|
|
self.find_element_by_link_text_in_table('nav', item)
|
|
except Exception:
|
|
self.assertFalse(True, msg=("link %s cannot be found in the page" % item))
|
|
# step 7 involved
|
|
check_list_3 = ['Machine', 'Distro', 'Layers', 'Total number of tasks', 'Tasks executed', \
|
|
'Tasks not executed', 'Reuse', 'Recipes built', 'Packages built']
|
|
self.assertTrue(self.is_text_present(check_list_3), msg=("text not in web page"))
|
|
self.driver.back()
|
|
|
|
|
|
##############
|
|
# CASE 951 #
|
|
##############
|
|
def test_951(self):
|
|
self.case_no = self.get_case_number()
|
|
self.log.info(' CASE %s log: ' % str(self.case_no))
|
|
self.driver.maximize_window()
|
|
self.driver.get(self.base_url)
|
|
# currently test case itself isn't responsible for creating "1 successful and
|
|
# 1 failed build"
|
|
has_successful_build = 1
|
|
has_failed_build = 1
|
|
try:
|
|
fail_icon = self.driver.find_element_by_xpath("//*[@class='icon-minus-sign error']")
|
|
except Exception:
|
|
has_failed_build = 0
|
|
self.log.info("no failed build exists")
|
|
pass
|
|
# if there's failed build, we can proceed
|
|
if has_failed_build:
|
|
self.driver.find_element_by_partial_link_text("error").click()
|
|
self.driver.back()
|
|
# not sure if there "must be" some warnings, so here save a screen
|
|
self.browser_delay()
|
|
self.save_screenshot(screenshot_type='selenium', append_name='step4')
|
|
|
|
|
|
##############
|
|
# CASE 955 #
|
|
##############
|
|
def test_955(self):
|
|
self.case_no = self.get_case_number()
|
|
self.log.info(' CASE %s log: ' % str(self.case_no))
|
|
self.driver.maximize_window()
|
|
self.driver.get(self.base_url)
|
|
self.log.info(" You should manually create all images before test starts!")
|
|
# So far the case itself is not responsable for creating all sorts of images.
|
|
# So assuming they are already there
|
|
# step 2
|
|
self.driver.find_element_by_link_text("core-image-minimal").click()
|
|
# save screen here to see the page component
|
|
|
|
|
|
##############
|
|
# CASE 956 #
|
|
##############
|
|
def test_956(self):
|
|
self.case_no = self.get_case_number()
|
|
self.log.info(' CASE %s log: ' % str(self.case_no))
|
|
self.driver.maximize_window()
|
|
self.driver.get(self.base_url)
|
|
# step 2-3 need to run manually
|
|
self.log.info("step 2-3: checking the help message when you hover on help icon of target,\
|
|
tasks, recipes, packages need to run manually")
|
|
self.driver.find_element_by_partial_link_text("Manual").click()
|
|
if not self.is_text_present("Manual"):
|
|
self.log.error("please check [Toaster manual] link on page")
|
|
self.failIf(True)
|
|
|
|
####################################################################################################
|
|
# Starting backend tests ###########################################################################
|
|
####################################################################################################
|
|
|
|
##############
|
|
# CASE 1066 #
|
|
##############
|
|
def test_1066(self):
|
|
self.case_no = self.get_case_number()
|
|
self.log.info(' CASE %s log: ' % str(self.case_no))
|
|
con=sqlite.connect('toaster.sqlite')
|
|
cursor = con.cursor()
|
|
query = "select count(name) from orm_project a, auth_user b where a.user_id = b.id and b.username='_anonuser';"
|
|
cursor.execute(query)
|
|
data = cursor.fetchone()
|
|
self.failUnless(data >= 1)
|
|
|
|
|
|
##############
|
|
# CASE 1071 #
|
|
##############
|
|
def test_1071(self):
|
|
self.case_no = self.get_case_number()
|
|
self.log.info(' CASE %s log: ' % str(self.case_no))
|
|
con=sqlite.connect('toaster.sqlite')
|
|
cursor = con.cursor()
|
|
query = "select name from orm_release;"
|
|
cursor.execute(query)
|
|
data = cursor.fetchall()
|
|
for i in range(0,4):
|
|
data[i] = data[i][0]
|
|
data.sort()
|
|
print(data)
|
|
json_parse = json.loads(open('toasterconf.json').read())
|
|
json_data = []
|
|
for i in range (0,4):
|
|
json_data.append(json_parse['releases'][i]['name'])
|
|
json_data.sort()
|
|
print(json_data)
|
|
self.failUnless(data == json_data)
|
|
|
|
##############
|
|
# CASE 1072 #
|
|
##############
|
|
def test_1072(self):
|
|
self.case_no = self.get_case_number()
|
|
self.log.info(' CASE %s log: ' % str(self.case_no))
|
|
con=sqlite.connect('toaster.sqlite')
|
|
cursor = con.cursor()
|
|
query = "select value from orm_toastersetting where name like 'DEFCONF%';"
|
|
cursor.execute(query)
|
|
data = cursor.fetchall()
|
|
for i in range(0,6):
|
|
data[i] = data[i][0]
|
|
print(data)
|
|
json_parse = json.loads(open('toasterconf.json').read())
|
|
json_data=json_parse['config']
|
|
json_data = json_data.values()
|
|
print(json_data)
|
|
self.failUnless(data == json_data)
|
|
|
|
|
|
##############
|
|
# CASE 1074 #
|
|
##############
|
|
def test_1074(self):
|
|
self.case_no = self.get_case_number()
|
|
self.log.info(' CASE %s log: ' % str(self.case_no))
|
|
con=sqlite.connect('toaster.sqlite')
|
|
cursor = con.cursor()
|
|
query = "select name from orm_layersource;"
|
|
cursor.execute(query)
|
|
data = cursor.fetchall()
|
|
for i in range(0,3):
|
|
data[i] = data[i][0]
|
|
print(data)
|
|
json_parse = json.loads(open('toasterconf.json').read())
|
|
json_data = []
|
|
for i in range(0,3):
|
|
json_data.append(json_parse['layersources'][i]['name'])
|
|
print(json_data)
|
|
self.failUnless(set(data) == set(json_data))
|
|
|
|
##############
|
|
# CASE 1075 #
|
|
##############
|
|
def test_1075(self):
|
|
self.case_no = self.get_case_number()
|
|
self.log.info(' CASE %s log: ' % str(self.case_no))
|
|
con=sqlite.connect('toaster.sqlite')
|
|
cursor = con.cursor()
|
|
query = "select value from orm_toastersetting where name like 'DEFAULT_RELEASE';"
|
|
cursor.execute(query)
|
|
data = cursor.fetchall()
|
|
data = data[0][0]
|
|
print(data)
|
|
json_parse = json.loads(open('toasterconf.json').read())
|
|
json_data = json_parse['defaultrelease']
|
|
print(json_data)
|
|
self.failUnless(set(data) == set(json_data))
|
|
|
|
##############
|
|
# CASE 1076 #
|
|
##############
|
|
def test_1076(self):
|
|
self.case_no = self.get_case_number()
|
|
self.log.info(' CASE %s log: ' % str(self.case_no))
|
|
|
|
print('Checking branches for "Local Yocto Project"')
|
|
con=sqlite.connect('toaster.sqlite')
|
|
cursor = con.cursor()
|
|
query = "select name from orm_branch where layer_source_id=1;"
|
|
cursor.execute(query)
|
|
data = cursor.fetchall()
|
|
lenght = len(data)
|
|
try:
|
|
for i in range(0,lenght):
|
|
data[i] = data[i][0]
|
|
except:
|
|
pass
|
|
print(data)
|
|
json_parse = json.loads(open('toasterconf.json').read())
|
|
json_location = json_parse['layersources'][0]['name']
|
|
print(json_location)
|
|
json_data = json_parse['layersources'][0]['branches']
|
|
print(json_data)
|
|
self.failUnless(set(data) == set(json_data))
|
|
|
|
print('Checking branches for "OpenEmbedded"')
|
|
con=sqlite.connect('toaster.sqlite')
|
|
cursor = con.cursor()
|
|
query = "select name from orm_branch where layer_source_id=3;"
|
|
cursor.execute(query)
|
|
data = cursor.fetchall()
|
|
lenght = len(data)
|
|
for i in range(0,lenght):
|
|
data[i] = data[i][0]
|
|
print(data)
|
|
json_parse = json.loads(open('toasterconf.json').read())
|
|
json_location = json_parse['layersources'][1]['name']
|
|
print(json_location)
|
|
json_data = json_parse['layersources'][1]['branches']
|
|
print(json_data)
|
|
self.failUnless(set(data) == set(json_data))
|
|
|
|
print('Checking branches for "Imported layers"')
|
|
con=sqlite.connect('toaster.sqlite')
|
|
cursor = con.cursor()
|
|
query = "select name from orm_branch where layer_source_id=2;"
|
|
cursor.execute(query)
|
|
data = cursor.fetchall()
|
|
lenght = len(data)
|
|
for i in range(0,lenght):
|
|
data[i] = data[i][0]
|
|
print(data)
|
|
json_parse = json.loads(open('toasterconf.json').read())
|
|
json_location = json_parse['layersources'][2]['name']
|
|
print(json_location)
|
|
json_data = json_parse['layersources'][2]['branches']
|
|
print(json_data)
|
|
self.failUnless(set(data) == set(json_data))
|
|
|
|
|
|
##############
|
|
# CASE 1077 #
|
|
##############
|
|
def test_1077(self):
|
|
self.case_no = self.get_case_number()
|
|
self.log.info(' CASE %s log: ' % str(self.case_no))
|
|
con=sqlite.connect('toaster.sqlite')
|
|
cursor = con.cursor()
|
|
query = "select name from orm_bitbakeversion;"
|
|
cursor.execute(query)
|
|
data = cursor.fetchall()
|
|
for i in range(0,4):
|
|
data[i] = data[i][0]
|
|
print(data)
|
|
json_parse = json.loads(open('toasterconf.json').read())
|
|
json_data = []
|
|
for i in range(0,4):
|
|
json_data.append(json_parse['bitbake'][i]['name'])
|
|
print(json_data)
|
|
self.failUnless(set(data) == set(json_data))
|
|
|
|
##############
|
|
# CASE 1083 #
|
|
##############
|
|
def test_1083(self):
|
|
self.case_no = self.get_case_number()
|
|
self.log.info(' CASE %s log: ' % str(self.case_no))
|
|
self.driver.maximize_window()
|
|
self.driver.get(self.base_url)
|
|
self.driver.find_element_by_id("new-project-button").click()
|
|
self.driver.find_element_by_id("new-project-name").send_keys("new-test-project")
|
|
self.driver.find_element_by_id("create-project-button").click()
|
|
con=sqlite.connect('toaster.sqlite')
|
|
cursor = con.cursor()
|
|
query = "select count(name) from orm_project where name = 'new-test-project';"
|
|
cursor.execute(query)
|
|
data = cursor.fetchone()
|
|
print('data: %s' % data)
|
|
self.failUnless(data >= 1)
|
|
|
|
##############
|
|
# CASE 1084 #
|
|
##############
|
|
def test_1084(self):
|
|
self.case_no = self.get_case_number()
|
|
self.log.info(' CASE %s log: ' % str(self.case_no))
|
|
self.driver.maximize_window()
|
|
self.driver.get(self.base_url)
|
|
self.driver.find_element_by_id("new-project-button").click()
|
|
self.driver.find_element_by_id("new-project-name").send_keys("new-default-project")
|
|
self.driver.find_element_by_id("create-project-button").click()
|
|
con=sqlite.connect('toaster.sqlite')
|
|
cursor = con.cursor()
|
|
query = "select a.name from orm_release a, orm_project b where a.id = b.release_id and b.name = 'new-default-project' limit 1;"
|
|
cursor.execute(query)
|
|
db_data = str(cursor.fetchone()[0])
|
|
json_parse = json.loads(open('toasterconf.json').read())
|
|
json_data = str(json_parse['defaultrelease'])
|
|
self.failUnless(db_data == json_data)
|
|
|
|
##############
|
|
# CASE 1088 #
|
|
##############
|
|
def test_1088(self):
|
|
self.case_no = self.get_case_number()
|
|
self.log.info(' CASE %s log: ' % str(self.case_no))
|
|
self.driver.maximize_window()
|
|
self.driver.get(self.base_url)
|
|
self.driver.find_element_by_css_selector("a[href='/toastergui/projects/']").click()
|
|
self.driver.find_element_by_link_text('new-default-project').click()
|
|
self.driver.find_element_by_id('project-change-form-toggle').click()
|
|
self.driver.find_element_by_id('project-name-change-input').clear()
|
|
self.driver.find_element_by_id('project-name-change-input').send_keys('new-name')
|
|
self.driver.find_element_by_id('project-name-change-btn').click()
|
|
con=sqlite.connect('toaster.sqlite')
|
|
cursor = con.cursor()
|
|
query = "select count(name) from orm_project where name = 'new-name';"
|
|
cursor.execute(query)
|
|
data = cursor.fetchone()[0]
|
|
self.failUnless(data == 1)
|
|
#reseting project name
|
|
self.driver.find_element_by_id('project-change-form-toggle').click()
|
|
self.driver.find_element_by_id('project-name-change-input').clear()
|
|
self.driver.find_element_by_id('project-name-change-input').send_keys('new-default-project')
|
|
self.driver.find_element_by_id('project-name-change-btn').click()
|
|
|
|
|
|
##############
|
|
# CASE 1089 #
|
|
##############
|
|
def test_1089(self):
|
|
self.case_no = self.get_case_number()
|
|
self.log.info(' CASE %s log: ' % str(self.case_no))
|
|
self.driver.maximize_window()
|
|
self.driver.get(self.base_url)
|
|
self.driver.find_element_by_css_selector("a[href='/toastergui/projects/']").click()
|
|
self.driver.find_element_by_link_text('new-default-project').click()
|
|
self.driver.find_element_by_id('change-machine-toggle').click()
|
|
self.driver.find_element_by_id('machine-change-input').clear()
|
|
self.driver.find_element_by_id('machine-change-input').send_keys('qemuarm64')
|
|
# self.driver.find_element_by_id('machine-change-input').send_keys(Keys.RETURN)
|
|
self.driver.find_element_by_id('machine-change-btn').click()
|
|
con=sqlite.connect('toaster.sqlite')
|
|
cursor = con.cursor()
|
|
query = "select count(id) from orm_projectvariable where name like 'machine' and value like 'qemuarm64';"
|
|
cursor.execute(query)
|
|
data = cursor.fetchone()[0]
|
|
self.failUnless(data == 1)
|
|
#resetting machine to default value
|
|
self.driver.find_element_by_id('change-machine-toggle').click()
|
|
self.driver.find_element_by_id('machine-change-input').clear()
|
|
self.driver.find_element_by_id('machine-change-input').send_keys('qemux86')
|
|
self.driver.find_element_by_id('machine-change-input').send_keys(Keys.RETURN)
|
|
self.driver.find_element_by_id('machine-change-btn').click()
|
|
|
|
##############
|
|
# CASE 1090 #
|
|
##############
|
|
def test_1090(self):
|
|
self.case_no = self.get_case_number()
|
|
self.log.info(' CASE %s log: ' % str(self.case_no))
|
|
con=sqlite.connect('toaster.sqlite')
|
|
cursor = con.cursor()
|
|
query = "select username from auth_user where is_superuser = 1;"
|
|
cursor.execute(query)
|
|
data = cursor.fetchall()
|
|
try:
|
|
data = data[0][0]
|
|
except:
|
|
pass
|
|
print(data)
|
|
self.failUnless(data == 'toaster_admin')
|
|
|
|
##############
|
|
# CASE 1091 #
|
|
##############
|
|
def test_1091(self):
|
|
self.case_no = self.get_case_number()
|
|
self.log.info(' CASE %s log: ' % str(self.case_no))
|
|
self.driver.maximize_window()
|
|
self.driver.get(self.base_url)
|
|
self.driver.find_element_by_css_selector("a[href='/toastergui/projects/']").click()
|
|
self.driver.find_element_by_link_text('new-default-project').click()
|
|
self.driver.find_element_by_id('release-change-toggle').click()
|
|
dropdown = self.driver.find_element_by_css_selector('select')
|
|
for option in dropdown.find_elements_by_tag_name('option'):
|
|
if option.text == 'Local Yocto Project':
|
|
option.click()
|
|
self.driver.find_element_by_id('change-release-btn').click()
|
|
#wait for the changes to register in the DB
|
|
time.sleep(1)
|
|
con=sqlite.connect('toaster.sqlite')
|
|
cursor = con.cursor()
|
|
query = "select count(*) from orm_layer_version a, orm_projectlayer b, orm_project c where a.\"commit\"=\"HEAD\" and a.id = b.layercommit_id and b.project_id=c.id and c.name='new-default-project';"
|
|
cursor.execute(query)
|
|
data = cursor.fetchone()[0]
|
|
#resetting release to default
|
|
self.driver.find_element_by_id('release-change-toggle').click()
|
|
dropdown = self.driver.find_element_by_css_selector('select')
|
|
for option in dropdown.find_elements_by_tag_name('option'):
|
|
if option.text == 'Yocto Project master':
|
|
option.click()
|
|
self.driver.find_element_by_id('change-release-btn').click()
|
|
#wait for the changes to register in the DB
|
|
time.sleep(1)
|
|
self.failUnless(data == 3)
|
|
|
|
##############
|
|
# CASE 1092 #
|
|
##############
|
|
def test_1092(self):
|
|
self.case_no = self.get_case_number()
|
|
self.log.info(' CASE %s log: ' % str(self.case_no))
|
|
self.driver.maximize_window()
|
|
con=sqlite.connect('toaster.sqlite')
|
|
cursor = con.cursor()
|
|
query = "select a.name, a.value from orm_projectvariable a, orm_project b where a.project_id = b.id and b.name = 'new-default-project';"
|
|
cursor.execute(query)
|
|
data = dict(cursor.fetchall())
|
|
print(data)
|
|
default_values = {u'IMAGE_INSTALL_append': u'', u'PACKAGE_CLASSES': u'package_rpm', u'MACHINE': u'qemux86', u'SDKMACHINE': u'x86_64', u'DISTRO': u'poky', u'IMAGE_FSTYPES': u'ext3 jffs2 tar.bz2'}
|
|
self.failUnless(data == default_values)
|
|
|
|
##############
|
|
# CASE 1093 #
|
|
##############
|
|
def test_1093(self):
|
|
self.case_no = self.get_case_number()
|
|
self.log.info(' CASE %s log: ' % str(self.case_no))
|
|
|
|
#get initial values
|
|
con=sqlite.connect('toaster.sqlite')
|
|
cursor = con.cursor()
|
|
query = "select layercommit_id from orm_projectlayer a, orm_project b where a.project_id=b.id and b.name='new-default-project';"
|
|
cursor.execute(query)
|
|
data_initial = cursor.fetchall()
|
|
print(data_initial)
|
|
|
|
self.driver.maximize_window()
|
|
self.driver.get('localhost:8000')#self.base_url)
|
|
self.driver.find_element_by_css_selector("a[href='/toastergui/projects/']").click()
|
|
self.driver.find_element_by_link_text('new-default-project').click()
|
|
self.driver.find_element_by_id('release-change-toggle').click()
|
|
dropdown = self.driver.find_element_by_css_selector('select')
|
|
for option in dropdown.find_elements_by_tag_name('option'):
|
|
if option.text == 'Local Yocto Project':
|
|
option.click()
|
|
self.driver.find_element_by_id('change-release-btn').click()
|
|
#wait for the changes to register in the DB
|
|
time.sleep(1)
|
|
|
|
#get changed values
|
|
con=sqlite.connect('toaster.sqlite')
|
|
cursor = con.cursor()
|
|
query = "select layercommit_id from orm_projectlayer a, orm_project b where a.project_id=b.id and b.name='new-default-project';"
|
|
cursor.execute(query)
|
|
data_changed = cursor.fetchall()
|
|
print(data_changed)
|
|
|
|
#resetting release to default
|
|
self.driver.find_element_by_id('release-change-toggle').click()
|
|
dropdown = self.driver.find_element_by_css_selector('select')
|
|
for option in dropdown.find_elements_by_tag_name('option'):
|
|
if option.text == 'Yocto Project master':
|
|
option.click()
|
|
self.driver.find_element_by_id('change-release-btn').click()
|
|
#wait for the changes to register in the DB
|
|
time.sleep(1)
|
|
self.failUnless(data_initial != data_changed)
|