from action import *
import action as ac
from bin import *
from bs4 import BeautifulSoup
try:
import xlrd
except:
run_cmd("pip install xlrd")
import xlrd
import lxml
#选择需要运行的功能和环境
def select():
print("------------------------欢迎来到uss2.0ui自动化系统-----------------")
caidan = {"1": ["登录",login],
"2":["品牌",Brand_management] ,
"3": ["品类",Category_Management],
"4": ["小类",xl],
"5": ["需求小类",xqxl],
"6": ["产品型号",Item],
"7": ["故障现象",Fault_phenomenon],
"8": ["故障部位",Fault_location],
"9": ["故障原因",Fix_reason],
"10":[ "维修措施",Fix_method],
"11": ["故障树",Fault_tree],
"12": ["特设费用",TSFY],
"13": ["节点短信模板",jddx],
"14": ["奖罚规则",jfgz],
"15": ["受理问题",slwt],
"16": ["SKU",SKU],
"17": ["字典维护",ZD],
"18": ["服务方式",fwfs],
"19": ["服务分类",fwfl],
"20": ["服务分类参数",fwflcs],
"21": ["完工图片",wgtp],
"22": ["用户账号",yhzh],
"23": ["工单险",gdx],
"24": ["统收统付新增归类名称",xzcsgl],
"25": ["人工费收取设置",rgf],
# "26": ["坐席技能",zxjn],
# "27": ["修改维修措施",xgwxcs],
"28": ["维修归类",xzwxgl]}
print(f"以下是我们目前支持的功能,请选择:")
for i,k in caidan.items():
print(fr"{i}、{k[0]}")
caidan_name_gn= {}
while 1:
gn_list=input("------请选择你要输入的功能------")
if "," in gn_list or "、" in gn_list:
gn_list=gn_list.replace(",",",")
gn_list=gn_list.replace("、", ",")
gn_list=gn_list.split(",")
try:
zx_list=[]
for gn in gn_list:
zx = caidan[gn][1]
zx_list.append(zx)
caidan_name_gn[caidan[gn][0]]=zx
break
except:
print("功能选择错误")
environment = {"1": "uat",
"2": "sit",
"3": "生产"}
while 1:
try:
HJ =environment[input(f"------请输入你要运行的环境,请选择:{environment}------")]
break
except:
print("环境选择错误,请重新输入运行环境")
return HJ,caidan_name_gn
#选择文件及目录
def runfile():
fail_list_mag=[]
fail_dict={}
#确认运行环境以及执行方法
HJ, caidan_name_gn= select()
#根据执行方法查找同名得文件数据
run_function_datalist={}
print(f"正在查找文件...")
#根据功能获取文件
for filename in caidan_name_gn:
# 先查找与功能有关的文件
file_stuta, file_name_path = get_file_name(test_path, filename)
# 如果查找成功并且只查到唯一符合条件的功能就
if file_stuta and len(file_name_path)==1:
# 读取数据
file_stuta1, file_data = read_rows_cols(file_name_path)
# 如果读取成功则前置校验通过
if file_stuta1:
print(f"{file_name_path}读取成功")
run_function_datalist[f"{file_name_path[0]}"]=[file_name_path[0],filename,file_data,caidan_name_gn[filename],HJ]
# 如果读取失败则直接中断程序,直接报错
else:
fail_list_mag.append(file_data)
return False,fail_list_mag
# 如果查找失败/查找到的文件不唯一
else:
# 循环查找文件,直到成功为止
while 1:
# 如果查找成功,文件有多个则手动选择文件
if file_stuta :
if len(file_name_path)>=2:
print("----查找到多个符合条件的文件------")
file_dir={}
NUM=1
# 遍历文件列表
for file in file_name_path:
file_dir[f"{NUM}"]=file
print(f"{NUM}:{file}")
NUM+=1
while 1:
try:
# 选择想要的文件
file_name= file_dir[input("请选择正确的文件:")]
file_name_path=[]
file_name_path.append(file_name)
break
except:
pass
# 读取选择的文件
file_stuta1, file_data = read_rows_cols(file_name_path)
# 如果读取文件成功则前置校验成功
if file_stuta1:
run_function_datalist[f"{file_name_path[0]}"] = [file_name_path[0], filename, file_data,caidan_name_gn[filename], HJ]
print(f"{file_name_path[0]}读取成功")
break
# 如果读取失败了,则从头开始手动选择
else:
print(f"{file_name_path[0]}读取失败:{file_data}")
file_stuta = False
# 如果查询成功并且只查询到一条数据
else:
# 读取文件
file_stuta1, file_data = read_rows_cols(file_name_path)
# 如果读取文件成功则前置校验成功
if file_stuta1:
run_function_datalist[f"{file_name_path[0]}"] = [file_name_path[0], filename, file_data,caidan_name_gn[filename], HJ]
print(f"{file_name_path[0]}读取成功")
break
#如果读取失败了,则从头开始手动选择
else:
file_stuta=False
# 如果查找失败则手动选择
else:
print(f"'---------{filename}'{file_name_path[0]}-----")
statu,file_name_path = get_file_name_path(test_path)
if statu and "该功能被取消执行" in file_name_path[0]:
break

print("前置条件校验通过,即将打开浏览器请稍后...")
#运行登录
stuta, msg = environment_click(login, HJ)
if stuta:
# menu_path={}
deveces = msg
# 获取对应文件所在得菜单层级
for menu_name in run_function_datalist:
# 保留原始数据中的key留作后用
diename = menu_name
# 获取文件目录完整名字并去除空格
menu_name = menu_name.replace(" ", "")
# 根据斜杠拆字符串
menu_name = menu_name.split("\\")
# 取左后一个斜杠后面的内容
menu_name=menu_name[-1]
# 根据下划线拆分文件名称并取第二个的部分作为目录的名字
if "-"in menu_name:
menu_name=menu_name.split("-")
menu_name=menu_name[1]
elif "—" in menu_name:
menu_name = menu_name.split("—")
menu_name = menu_name[1]
elif "_"in menu_name:
menu_name=menu_name.split("_")
menu_name=menu_name[1]
else:
menu_name = menu_name.split(".")
menu_name=menu_name[0]
path_bin={}
# print(menu_name)
#根据目录名称获取目录的路径
stuta2,path1=get_uss_menu(deveces,menu_name)
if stuta2:
# 如果匹配到多个路径
if len(path1)>1:
num = 1
for i in path1:
print(f"{num}:{i}")
path_bin[f"{num}"]=i
num+=1
# 匹配到多个路径则根据选择来确定最终的路径
path1=path_bin[input(f"检测到符合条件的有多个目录,请选择执行哪个目录:")]
else:
path1=path1[0]
# 保存目录的路径
run_function_datalist[f"{diename}"].append(path1)
else:
fail_list_mag.append(path1)
return False,fail_list_mag
else:
print(msg)
# 遍历执行的数据根据数据取执行功能
for functionkey, value in run_function_datalist.items():
# 执行功能
stuta,msg=run_function(value[0],value[1], value[2], value[3], value[4],deveces,value[5])
# 打印本次运行的结果
# print(msg)
# 打印文件名称告诉日志该文件已执行完毕
print(f"{value[1]}执行完成")
# 把执行结果加入失败列表
fail_dict[value[1]]=msg
# 把失败列表加入到最后的总失败原因集合里面来
fail_list_mag.append(fail_dict)
# 执行完之后关闭浏览器
deveces.close()
return True, fail_list_mag
#获取执行文件名在uss目录得位置
def get_uss_menu(deveces,children_menu_text):
# print(children_menu_text)
mnue_path=[]
text = deveces.page_source
text = BeautifulSoup(text, "lxml")
mue_list1_2_3 = []
mue_list2_3 = []
mue_list3 = []
mue_list2=[]
mue_list1=[]
#获取1-2-3级菜单关联
for i, ui123 in enumerate(
text.select('li[class="vue3-ts-admin-tpl-menu-submenu vue3-ts-admin-tpl-simple-menu__parent"]')):
mue_list1_2_3.append(ui123.get_text())
print(mue_list1_2_3)
# 获取2-3级菜单关联
for i, ui23 in enumerate(
text.select(
'li[class="vue3-ts-admin-tpl-menu-submenu vue3-ts-admin-tpl-menu-submenu-has-parent-submenu vue3-ts-admin-tpl-simple-menu__children"]')):
mue_list2_3.append(ui23.get_text())
# 获取3级菜单
for i, ui3 in enumerate(
text.select('li[class="vue3-ts-admin-tpl-menu-item vue3-ts-admin-tpl-simple-menu__children"]')):
mue_list3.append(ui3.get_text())
# 获取2级菜单
for i, ui2 in enumerate(
text.select('div>ul>li>ul>li>div[class="vue3-ts-admin-tpl-menu-submenu-title"]')):
mue_list2.append(ui2.get_text())
# 获取1级菜单关联
for i, ui1 in enumerate(
text.select('div >ul>li>div>span[class="ml-2 vue3-ts-admin-tpl-simple-menu-sub-title"]')):
mue_list1.append(ui1.get_text())
num=0
#获取三级目录
if children_menu_text in mue_list3:
for i in mue_list3:
if children_menu_text==i:
num+=1
else:
print(f"3级目录没有该菜单{children_menu_text}")
return False,f"3级目录没有该菜单{children_menu_text}"
# 当1-2-3级完整时
# 获取2级目录
for i in mue_list2_3:
menu2 = 1
menu1 = 1
if children_menu_text in i :
while 1:
if i[0:menu2] in mue_list2:
break
menu2+=1
#获取1级目录
for k in mue_list1_2_3:
if i in k:
while 1:
if k[0:menu1] in mue_list1:
mnue_path.append([children_menu_text,i[0:menu2],k[0:menu1]])
break
menu1+=1
# 当仅有1-3级时
children_num=0
for h in mue_list1_2_3:
if children_menu_text in h:
children_num+=1
if children_num==1:
return True,mnue_path
elif children_num==2:
if len(mnue_path)<children_num:
for t in mue_list1_2_3:
if children_menu_text in t:
for k in mnue_path:
menu1=1
try:
if k[2] not in t:
while 1:
if t[0:menu1] in mue_list1:
mnue_path.append([children_menu_text, t[0:menu1]])
break
menu1+=1
except:
pass
return True,mnue_path
#运行功能
def run_function(path,filename,value_dict,run_name,hj,deveces,meun_path_list):
try:
# 打开excel
data = xlrd.open_workbook(rf'{path}')
# 读取第一个sheet的内容
table = data.sheets()[0]
except_list=[]
# 获取所有sheet的名字
name = data.sheet_names()
# 获取行数
rows = table.nrows
# 获取列数
cols = table.ncols
except:
return False,rf"文件路径错误请及时查看path:{path}"
try:
sleep(3)
# 目录有三个代表有三级
if len(meun_path_list)==3 :
deveces.find_element(by="xpath", value=f"//span[text()='{meun_path_list[2]}']").click()
# 否则的话就只有两级
else:
deveces.find_element(by="xpath", value=f"//span[text()='{meun_path_list[1]}']").click()
# print("1级目录点击成功")
sleep(0.5)
# deveces.find_element(by="xpath", value="//span[text()='品类管理']").click()
try:
# 目录有三个代表有三级
print(meun_path_list)
if len(meun_path_list)==3:
deveces.find_element(by="xpath", value=f"(//span[text()='{meun_path_list[1]}'])").click()
# print("2级目录点击成功")
else:
pass
except:
num_2=2
while 1:
try:
# 如果二级存在多个相同的元素则一直点,直到点击不报错为止
deveces.find_element(by="xpath", value=f"(//span[text()='{meun_path_list[1]}'])[{num_2}]").click()
break
except:
num_2+=1
sleep(0.5)
try:
# 点击三级目录的
deveces.find_element(by="xpath", value=f'//li[@parent="false"]/span[text()="{meun_path_list[0]}"]').click()
except:
# 最大尝试次数
num_3_max=5
# 当前尝试次数
num_3=1
while 1:
try:
if num_3>num_3_max:
print(f"没有查到有该目录请检查3级目录是否正确:{meun_path_list[0]}")
return False,f"没有查到有该目录请检查3级目录是否正确:{meun_path_list[0]}"
# 如果三级有多个同名元素则一直点,知道点到超过num_3_max次为止
deveces.find_element(by="xpath", value=f'(//li[@parent="false"]/span[text()="{meun_path_list[0]}"])[{num_3}]').click()
break
except:
num_3+=1
# print("3级目录点击成功")
num = 1
table_list=[]
need_table=[]
table_header={}
i = 2
isremake=False
# 数据为空计数
none_num = 0
# 提前读取表头省去每次读数据时多次读同一个字段
header_excel = []
for col in range(0, cols):
# 读取表头
value1 = table.cell_value(0, col)
# 添加表头
header_excel.append(value1)
# 检查表头中是否含有备注或者只有数据没有表头
if ("备注" , ""," ") in header_excel :
# x_index = []
remake_index=[]
x_index=0
# 如果有备注则获取各个备注的下标集合
for remake in range(len(header_excel)):
if header_excel[remake] in ("备注" , ""," "):
remake_index.append(x_index)
x_index+=1
isremake=True
# 把备注从实际的数据里面删掉
cols_actual=cols-len(remake_index)
else:
cols_actual=cols
#这里是读取文件表格的内容
while i <= rows:
# 从第二行开始读
for row in range(1, rows):
value_dict={}
# lod_value_dict={}
# 从第一列开始读
for col in range(0, cols):
# 获取到数据
value = table.cell_value(row, col)
# 获取到数据对应的表头
value1 = header_excel[col]
# 如果读到为空则为空计数加1
if value in (""," "):
none_num+=1
else:
# 如果读到是字符,则去除前后空格
if type(value)==str:
value=value.strip()
# 如果读到的是整数则强转为整数类型
elif value % 1 == 0:
value = int(value)
else:
pass
# 如果表头是字符串则去除表头前后空格
if type(value1)==str:
value1 = value1.strip()
# lod_value_dict[value1] = value
# 把处理好的值组装好一一对应
value_dict[f"{value1}"] = f"{value}"
if "备注" not in value_dict :
value_dict["备注"]=""
# 把读取表格所有的数据
table_list.append(value_dict)
i+=1
# 判断文件内是否只有标题没有数据
if cols==none_num:
return table_list,"执行文件数据为空"
run_num = 1
#执行用例循环
for value_dict in tqdm(table_list):
try:
print(f"正在执行第{run_num}条数据...")
i += 1
#失败次数参数
fail_num = 1
print(value_dict)
#刷新页面
# deveces.refresh()
#执行用例
msg, fail_name, isdoble_statu = run_name(value_dict, deveces, run_num)
print("")
print(f"{filename}的第{run_num}条数据执行完毕,执行结果为:{msg}")
#失败重跑
while isdoble_statu in (True, "True", "true") and fail_num <=2:
print(rf"{fail_name}正在尝试第{fail_num}次重试...")
num += 1
msg, fail_name, isdoble_statu = run_name(value_dict, deveces, run_num)
print(f"重试结果为{msg}")
fail_num += 1
run_num += 1
# 把失败返回添加到备注里面
value_dict["备注"] = msg
need_table.append(value_dict)
except_list.append(f"{fail_name}{msg}")
# 打印详细的报错信息
except:
value_dict["备注"] = f"调用功能方法没有返回导致失败即将执行下一条数据,请检查{run_name}"
need_table.append(value_dict)
except_list.append(f"{filename}{value_dict['备注']}")
print(f"调用功能方法没有返回导致失败即将执行下一条数据,请检查{run_name}")
# 如果即将要写入的文件里面表头为备注或者空的一列数据置为空值
if isremake:
# 遍历备注所在的下标列表
for i in remake_index:
# 遍历整个列
for k in range(rows):
# 将备注数据清空
status,msg=excel_with(k, i, path, "", sheet_code=0)
if status:
pass
# 如果清空失败则直接返回失败原因
else:
except_list.append(msg)
return False, except_list

# 把备注写入表格
rw=1
for data in need_table:
# 写入备注数据
excel_with(rw, cols_actual, path, data["备注"], sheet_code=0)
rw += 1
# 写入表头
excel_with(0, cols_actual, path, "备注", sheet_code=0)
#打印详细的报错信息
except Exception as e:
except_type, except_value, except_traceback = sys.exc_info()
except_file = os.path.split(except_traceback.tb_frame.f_code.co_filename)[1]
exc_dict = {
"报错类型": except_type,
"报错信息": except_value,
"报错文件": except_file,
"报错行数": except_traceback.tb_lineno,
}
return "写入表格失败请联系谢伟文确认菜单功能与编号的对应关系", exc_dict
if len(except_list)==0:
except_list.append(f"{filename}该文件执行成功无报错")
return "该功能执行完毕请及时查看", except_list