提交 7607bced authored 作者: 陈泽健's avatar 陈泽健

根据展厅预定系统的巡检流程输出脚本程序。进一步调试会控界面部分元素定位失败的问题以及议题文件上传失败的问题。调试appium移动端脚本,控制手机进入腾讯会议查看会控界面是否正常

上级 d2728fdf
from appium.options.android import UiAutomator2Options
import logging
from selenium import webdriver
def app_setup_driver(platformName, platformVersion, deviceName, appPackage, appActivity):
desired_caps = {
'platformName': platformName, # 被测手机是安卓
'platformVersion': platformVersion, # 手机安卓版本,如果是鸿蒙系统,依次尝试 12、11、10 这些版本号
'deviceName': deviceName, # 设备名,安卓手机可以随意填写
'appPackage': appPackage, # 启动APP Package名称
'appActivity': appActivity, # 启动Activity名称
'unicodeKeyboard': True, # 自动化需要输入中文时填True
'resetKeyboard': True, # 执行完程序恢复原来输入法
'noReset': True, # 不要重置App
'newCommandTimeout': 6000,
'automationName': 'UiAutomator2',
'skipUnlock': True,
'autoGrantPermissions': True
}
logging.info(f"desired_caps参数:{desired_caps}")
try:
logging.info("正在初始化 Appium 驱动程序...")
driver = webdriver.Remote('http://localhost:4723/wd/hub',
options=UiAutomator2Options().load_capabilities(desired_caps))
logging.info("Appium 驱动程序初始化成功。")
return driver
except Exception as e:
logging.error(f"初始化驱动程序失败: {e}")
raise
\ No newline at end of file
......@@ -16,13 +16,14 @@ from selenium.webdriver.chrome.service import Service as ChromeService
from hytest import *
from selenium import webdriver
from selenium.common import TimeoutException, NoSuchElementException, ElementNotInteractableException
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from urllib.parse import urlencode
from datetime import datetime
from time import sleep
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.by import By
# 获取当前脚本的绝对路径
current_dir = os.path.dirname(os.path.abspath(__file__))
......@@ -214,6 +215,7 @@ def issue_send_and_upload(wd , issue_num, issue_name, issue_file_name):
"//div[@class='topicsHandleButton uploadFile']"),
wd)
sleep(2)
INFO("点击【选择文件】按钮")
upload_button = WebDriverWait(wd, 60).until(
EC.element_to_be_clickable((By.XPATH, "//label[@id='global-uploader-btn']")))
INFO("选择议题文件上传")
......@@ -649,4 +651,33 @@ def get_reportfile_send_dingding(report_title, report_url_prefix):
logging.info("自动化测试完成。")
# if __name__ == '__main__':
# get_reportfile_send_dingding("测试","http://192.168.1.166")
\ No newline at end of file
# get_reportfile_send_dingding("测试","http://192.168.1.166")
def double_click_and_drag(source_element_locator, target_element_locator, wd):
"""
实现元素从source_element双击后拖拽到target_element的功能
:param wd: WebDriver实例
:param source_element_locator: 拖拽起始元素的定位器
:param target_element_locator: 拖拽目标元素的定位器
"""
try:
# 找到源元素和目标元素
source_element = WebDriverWait(wd, 60).until(EC.visibility_of_element_located(source_element_locator))
target_element = WebDriverWait(wd, 60).until(EC.visibility_of_element_located(target_element_locator))
# 使用ActionChains执行双击操作
actions = ActionChains(wd)
actions.double_click(source_element).perform()
# 等待双击操作生效
WebDriverWait(wd, 10).until(EC.staleness_of(source_element))
# 使用ActionChains执行拖拽操作
actions.drag_and_drop(source_element, target_element).perform()
except TimeoutException as e:
logging.error(f"元素查找超时: {e}")
except NoSuchElementException as e:
logging.error(f"元素未找到: {e}")
except Exception as e:
logging.error(f"发生未知错误: {e}")
\ No newline at end of file
......@@ -88,4 +88,6 @@
- 调整admin_login函数为传参形式。
- 补充展厅巡检流程,预定SMC视讯会议,并进行安卓信息截屏。后续补充会控操作功能流程进行调试。
26. 2024-12-10
- 调整browser_init函数改为传参方式传入登录页面URL,调整相关脚本的函数调用。
\ No newline at end of file
- 调整browser_init函数改为传参方式传入登录页面URL,调整相关脚本的函数调用。
- 根据展厅预定系统的巡检流程输出脚本程序。进一步调试会控界面部分元素定位失败的问题以及议题文件上传失败的问题。
- 调试appium移动端脚本,控制手机进入腾讯会议查看会控界面是否正常
\ No newline at end of file
from datetime import datetime, timedelta
from time import sleep
from datetime import timedelta
import sys
import os
# 获取当前脚本的绝对路径
......@@ -23,7 +22,7 @@ class Exhibition_hall_inspection_000x:
"""
执行指令:
1.cd 预定系统
2.hytest --report_title 会议预约测试报告 --test 会议预约_0**
2.hytest --report_title 会议预约测试报告 --report_url_prefix http://nat.ubainsyun.com:31133 --test 展厅巡检_0**
"""
ddt_cases = read_csv_data(csv_file_path)
......@@ -54,7 +53,7 @@ class Exhibition_hall_inspection_000x:
# 从全局存储中获取webdriver实例
wd = GSTORE['wd']
name = self.name
conference_name, message_name, message_type, book_type, repetitive_cycle, host_name, message_content, issue_name, book_start_time, book_end_time, inside_participant_name, outside_participant_name, outside_participant_phone, save_template, template_name, message_notification, notification_method, check_text = self.para
conference_name,message_name,book_type,issue_name,book_start_time,book_end_time,inside_participant_name,message_notification,notification_method,check_text = self.para
# 在会议室列表搜索会议室
STEP(1, f"在会议室列表搜索:{conference_name}")
......@@ -82,40 +81,25 @@ class Exhibition_hall_inspection_000x:
# 在会议预定第一步界面进行数据填入
STEP(3,"会议第一步数据填写")
INFO(f"输入会议名称:{message_name},选择会议类型:{message_type},选择预约类型:{book_type},输入主持人:{host_name},输入会议内容:{message_content},选择会议开始时间:{book_start_time},选择会议结束时间:{book_end_time}")
INFO(f"输入会议名称:{message_name},选择会议类型:视讯融合会议,选择预约类型:{book_type},选择会议开始时间:{book_start_time},选择会议结束时间:{book_end_time}")
# 输入会议名称
safe_send_keys((By.XPATH, "//input[@placeholder='请输入会议名称']"),message_name,wd)
# 判断会议类型
safe_click((By.XPATH, f"//div[@class='reserve_input']//span[@class='el-checkbox__label'][normalize-space()='{message_type}']"),wd)
sleep(1)
# 判断预约类型
if message_type == "":
if book_type == "普通会议":
INFO("预约类型为:普通会议")
# 选择普通会议
safe_click((By.XPATH, f"//span[contains(text(),'{book_type}')]"), wd)
sleep(1)
elif book_type == "周期会议":
INFO("预约类型为:周期会议")
# 选择周期会议
safe_click((By.XPATH, f"//span[contains(text(),'{book_type}')]"), wd)
sleep(1)
# 选择重复周期
safe_click((By.XPATH, f"//span[contains(text(),'{repetitive_cycle}')]"), wd)
sleep(1)
# 输入会议主持人
safe_send_keys((By.XPATH, "//input[@placeholder='请输入']"),host_name,wd)
# 输入会议内容
safe_send_keys((By.XPATH, "//textarea[@placeholder='请输入会议内容']"),message_content,wd)
safe_click((By.XPATH, f"//div[@class='reserve_input']//span[@class='el-checkbox__label'][normalize-space()='SMC3.0视频会议']"),wd)
safe_click((By.XPATH, f"//div[@class='reserve_input']//span[@class='el-checkbox__label'][normalize-space()='讯飞语音转录']"),wd)
safe_click((By.XPATH, f"//div[@class='reserve_input']//span[@class='el-checkbox__label'][normalize-space()='腾讯会议']"),wd)
sleep(2)
# 预约类型
INFO("预约类型为:普通会议")
# 选择普通会议
safe_click((By.XPATH, f"//span[contains(text(),'{book_type}')]"), wd)
sleep(1)
# 调用函数添加议题
INFO("添加议题文件")
issue_send_and_upload(wd, 2, issue_name, "议题图片.png")
# issue_send_and_upload(wd, 2, issue_name, "议题图片.png")
# 将字符串转换为时间对象
start_time = datetime.strptime(book_start_time, time_format)
......@@ -182,28 +166,10 @@ class Exhibition_hall_inspection_000x:
notify_text = elment_get_text((By.XPATH, f"//span[normalize-space()='{inside_participant_name}']"),wd)
INFO(f"已选择参会人:{notify_text}")
INFO(f"输入外部参会人名称:{outside_participant_name},外部参会人号码:{outside_participant_phone}")
# 点击【添加外部参会人】按钮
safe_click((By.XPATH,"(//span[contains(text(),'添加外部参会人员')])[1]"),wd)
sleep(1)
INFO("检查弹窗标题是否正确")
notify_text = elment_get_text((By.XPATH, "//span[contains(@class,'el-dialog__title')][contains(text(),'添加外部参会人员')]"),wd)
INFO(f"弹窗标题为:{notify_text}")
#输入外部参会人名称、外部参会人号码
safe_send_keys((By.XPATH,"//div[contains(@class,'add_input')]//input[contains(@placeholder,'用户名')]"),outside_participant_name,wd)
safe_send_keys((By.XPATH,"//input[@placeholder='手机号码']"),outside_participant_phone,wd)
sleep(1)
# 点击【确定】按钮
safe_click((By.XPATH,"//div[@aria-label='添加外部参会人员']//div[@class='el-dialog__footer']//button[@type='button']"),wd)
sleep(1)
# 检查提示信息是否正确
notify_text = get_notify_text(wd,(By.XPATH,"//p[contains(@class,'el-message__content')]"),"Message_Manage","Message_Book",f"{name}_添加外部参会人提示信息")
INFO(f"提示信息为:{notify_text}")
# 点击【下一步】按钮
safe_click((By.XPATH,"//div[contains(text(),'下一步')]"),wd)
sleep(1)
safe_click((By.XPATH,"//div[contains(text(),'下一步')]"),wd)
# 进入会议预约第三步进行填写
STEP(5, "会议第三步数据填写")
......@@ -213,19 +179,6 @@ class Exhibition_hall_inspection_000x:
notify_text = elment_get_text((By.XPATH,"//h2[contains(text(),'消息提醒')]"),wd)
INFO(f"页面标题为:{notify_text}")
# 判断是否需要存入模板
INFO(f"是否需要存入模板:{save_template}")
if save_template == "是":
# 点击【是】按钮
safe_click((By.XPATH,f"//span[@class='el-radio__label'][contains(text(),'{save_template}')]"),wd)
# 输入模板名称
safe_send_keys((By.XPATH,"//input[@placeholder='请输入模版名称']"),template_name,wd)
sleep(1)
else:
# 点击【否】按钮
safe_click((By.XPATH, f"//span[@class='el-radio__label'][contains(text(),'{save_template}')]"), wd)
sleep(1)
# 选择消息提醒时间
INFO(f"选择消息提醒时间:{message_notification}")
# 判断消息提醒时间是否为全选
......@@ -252,35 +205,24 @@ class Exhibition_hall_inspection_000x:
STEP(6, "点击【确定】按钮")
safe_click((By.XPATH,"//div[contains(text(),'确定')]"),wd)
# 检查会议信息是否正确
STEP(7, "检查提示会议信息是否正确")
sleep(1)
INFO(
f"检查会议名称:{message_name},输入会议内容:{message_content}")
# 点击最后【确定】按钮,预定成功后会跳转至已预定界面
STEP(8, "点击【确定】按钮")
STEP(7, "点击【确定】按钮")
safe_click((By.XPATH,"//div[contains(@aria-label,'会议信息')]//span[contains(text(),'确定')]"),wd)
sleep(1)
# 查看是否显示加载中
notify_text = elment_get_text((By.XPATH,"//p[@class='el-loading-text']"),wd)
sleep(1)
sleep(3)
# 获取提示信息
notify_text = get_notify_text(wd,(By.XPATH,"//p[contains(@class,'el-message__content')]"),"Message_Manage","Message_Book",f"{name}_预定成功提示信息")
INFO(f"预定成功提示信息为:{notify_text}")
sleep(10)
# 搜索会议名称
safe_send_keys((By.XPATH,"//input[@placeholder='输入关键字搜索']"),message_name,wd)
send_keyboard((By.XPATH,"//input[@placeholder='输入关键字搜索']"), wd)
# 在已预定列表界面【提前开始】会议
INFO("提前开始会议")
safe_click((By.XPATH,"(//span[contains(text(),'更多操作')])[1]"),wd)
safe_click((By.XPATH,"(//li[contains(@class,'el-dropdown-menu__item')][contains(text(),'会议状态')])[2]"),wd)
safe_click((By.XPATH,"//span[contains(text(),'更多操作')]"),wd)
safe_click((By.XPATH,"//li[contains(text(),'会议状态')]"),wd)
sleep(2)
safe_click((By.XPATH,"(//span[contains(text(),'确定')])[12]"),wd)
sleep(5)
safe_click((By.XPATH,"//div[@slot='footer']//span[contains(text(),'确定')]"),wd)
sleep(10)
STEP(9, "检查门口屏会议显示")
STEP(8, "检查门口屏会议显示")
# 进入后台-安卓信息界面截屏查看门口屏显示
safe_click((By.XPATH,"(//img[contains(@title,'后台系统')])[1]"),wd)
sleep(1)
......@@ -288,21 +230,62 @@ class Exhibition_hall_inspection_000x:
safe_click((By.XPATH,"(//li[contains(text(),'安卓信息')])[1]"),wd)
sleep(2)
safe_click((By.XPATH,"(//span[contains(text(),'应用截屏')])[1]"),wd)
sleep(5)
sleep(20)
# 截屏查看门口屏的显示
SELENIUM_LOG_SCREEN(wd, "50%", "Exhibit_Inspect", "Android", "截屏")
# 返回上一级界面
safe_click((By.XPATH,"//div[@aria-label='门口屏截屏']//i[@class='el-dialog__close el-icon el-icon-close']"), wd)
STEP(10, "检查会控界面功能")
STEP(9, "检查会控界面功能")
# 返回前台已预定列表界面
safe_click((By.XPATH,"(//img[@title='返回预定首页'])[1]"),wd)
safe_click((By.XPATH,"//img[@title='返回预定首页']"),wd)
sleep(1)
safe_click((By.XPATH,"(//span[contains(text(),'已预订会议')])[1]"),wd)
safe_click((By.XPATH,"//span[contains(text(),'已预订会议')]"),wd)
sleep(1)
# 点击【进入会控】
INFO("进入会控")
safe_click((By.XPATH,"(//span[contains(text(),'进入会控')])[1]"),wd)
safe_click((By.XPATH,"//span[contains(text(),'进入会控')]"),wd)
sleep(5)
# 切换窗口2,转到会控界面
wd.switch_to.window(wd.window_handles[1])
\ No newline at end of file
wd.switch_to.window(wd.window_handles[1])
# 会控操作
STEP(10, "检查会控界面功能")
INFO("检查会控界面功能")
# 添加SMC会场
INFO("添加SMC会场:展厅指挥中心、展厅会议室")
safe_click((By.XPATH,"//body/div[@id='app']/div[@id='Energy']/div[@class='main']/div[@class='mainList']/div[@class='main_l']/div[@class='mainFNC']/img[1]"),wd)
safe_send_keys((By.XPATH,"//input[@placeholder='搜索与会方']"),"展厅指挥中心",wd)
sleep(1)
send_keyboard((By.XPATH,"//input[@placeholder='搜索与会方']"), wd)
sleep(1)
safe_click((By.XPATH,"//div[contains(@class,'el-table el-table--fit el-table--enable-row-hover el-table--enable-row-transition')]//div[contains(@class,'el-table__header-wrapper')]//span[contains(@class,'el-checkbox__inner')]"),wd)
# 添加展厅指挥中心
INFO("添加腾讯会场")
safe_click((By.XPATH,"//div[@id='tab-TencentUser']"),wd)
safe_click((By.XPATH,"//li[normalize-space()='6']"),wd)
sleep(1)
safe_click((By.XPATH,"//li[normalize-space()='8']"),wd)
sleep(1)
safe_click((By.XPATH,"//body[1]/div[1]/div[1]/div[3]/div[1]/div[2]/div[1]/div[1]/div[1]/div[2]/div[3]/div[1]/div[1]/div[1]/div[3]/table[1]/tbody[1]/tr[7]/td[1]/div[1]/label[1]/span[1]/span[1]"),wd)
sleep(1)
safe_click((By.XPATH,"//div[contains(text(),'确定')]"),wd)
sleep(1)
# 一键呼叫会场
# safe_click((By.XPATH,"//body/div[@id='app']/div[@id='Energy']/div[contains(@class,'main')]/div[contains(@class,'mainList')]/div[contains(@class,'main_l')]/div[contains(@class,'mainFNC')]/img[1]"),wd)
# 选择分屏功能
safe_click((By.XPATH, "//li[4]//img[1]"), wd)
# 将左侧会场拖拽到右侧画面进行播放
INFO("将左侧会场拖拽到右侧画面进行播放")
double_click_and_drag((By.XPATH,"//div[contains(@class,'cell')]//span[contains(text(),'展厅指挥中心')]"), (By.XPATH,"//div[@id='screens4']//div[1]//p[1]//span[1]") , wd)
sleep(1)
double_click_and_drag((By.XPATH,"//div[@class='cell']//span[contains(text(),'391558766')]"), (By.XPATH,"//div[@id='screens4']//div[1]//p[1]//span[1]") , wd)
sleep(4)
SELENIUM_LOG_SCREEN(wd, "50%", "Exhibit_Inspect", "MeetingControl", "会场控制")
\ No newline at end of file
from 预定系统.Base.app_base import *
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from time import sleep
import logging
# 配置日志记录
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
def app_txcent_test():
app_drive = None
try:
app_drive = app_setup_driver("Android", "12", "RedmiK30Pro", "com.tencent.wemeet.app", ".StartupActivity")
app_drive.implicitly_wait(20) # 设置缺省等待时间
# 使用显式等待来等待元素出现
logging.info("等待登录页加载...")
WebDriverWait(app_drive, 60).until(EC.element_to_be_clickable((By.ID, "f7"))).click()
sleep(2)
WebDriverWait(app_drive, 60).until(EC.element_to_be_clickable((By.ID, "kr"))).click()
sleep(2)
WebDriverWait(app_drive, 60).until(EC.element_to_be_clickable((By.ID, "kr"))).send_keys("562483854")
sleep(5)
WebDriverWait(app_drive, 60).until(EC.element_to_be_clickable((By.ID, "y0"))).click()
except Exception as e:
logging.error(f"发生错误: {e}")
finally:
if app_drive: # 修改这里为 app_drive 而不是 driver
input('**** 按任意键退出..')
app_drive.quit()
logging.info("驱动程序已退出。")
if __name__ == '__main__':
app_txcent_test()
\ No newline at end of file
### Appium一些相关参数获取:
1. 如何获取手机某一程序的应用包名
使用adb命令进行获取,手机打开应用,adb命令行输入adb shell dumpsys activity recents | find "intent={" 找到第一行的cmp的key值appPackage/appActivity
![img.png](img.png)
### 运行Appium时遇到的问题总结:
1. 问题:运行Appium报错:
Failed to initialize driver: Message: An unknown server-side error occurred while processing the command. Original error: Error executing adbExec. Original error: 'Command ''C:\\Program Files\\androidsdk\\platform-tools\\adb.exe' -P 5037 -s f0b5fab1 shell settings delete global hidden_api_policy_pre_p_apps' exited with code 255'; Stderr: 'Exception occurred while executing 'delete':
解决方法:可能是权限不足导致,在adb命令行窗口输入adb root赋予权限。再执行程序
\ No newline at end of file
......@@ -4,4 +4,4 @@ tunnels:
nat1:
remote_port: 31133
proto:
tcp: "192.168.1.166:80"
\ No newline at end of file
tcp: "192.168.1.109:80"
\ No newline at end of file
name,conference_name,message_name,message_type,book_type,repetitive_cycle,host_name,message_content,issue_name,book_start_time,book_end_time,inside_participant_name,outside_participant_name,outside_participant_phone,save_template,template_name,message_notification,notification_method,check_text
展厅巡检_001,产研中心会议室,展厅巡检测试,SMC3.0,普通会议,每天,陈泽键,这是会议内容哈哈,议题1,20:15,20:30,admin@CZJ,陈泽坚,17319004674,否,这是模板,开会前一天提醒,短信,预定成功
\ No newline at end of file
name,conference_name,message_name,book_type,issue_name,book_start_time,book_end_time,inside_participant_name,message_notification,notification_method,check_text
展厅巡检_001,展厅会议室,展厅巡检测试,普通会议,议题1,12:00,12:15,CZJ,开会前一天提醒,短信,预定成功
\ No newline at end of file
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论