1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
from datetime import datetime, timedelta
from time import sleep
import sys
import os
# 获取当前脚本的绝对路径
current_dir = os.path.dirname(os.path.abspath(__file__))
# 构建预定系统的绝对路径
预定系统_path = os.path.abspath(os.path.join(current_dir, '..','..','..','..'))
# 添加路径
sys.path.append(预定系统_path)
# 导入模块
from 预定系统.Base.base import *
# 获取当前脚本所在的目录
current_dir = os.path.dirname(os.path.abspath(__file__))
# 构建CSV文件的绝对路径
csv_file_path = os.path.join(current_dir, '../../../测试数据/会议主流程/会议预约.csv')
# 定义时间格式
time_format = "%H:%M"
class Message_Book_000x:
tags = ['会议预约主流程','预定系统功能']
"""
执行指令:
1.cd 预定系统
2.hytest --report_title 会议预约测试报告 --test 会议预约_0**
"""
ddt_cases = read_csv_data(csv_file_path)
def teststeps(self):
"""
执行测试步骤以会议室删除功能。
本函数根据参数输入会议室名称进行搜索并删除会议室,并检查删除后的提示信息是否与预期相符。
字段含义:
name:用例名称
conference_name:会议室名称
message_name:会议名称
book_type:预约类型
repetitive_cycle:重复周期
host_name:主持人名称
message_content:会议内容
book_start_time:会议开始时间
book_end_time:会议结束时间
inside_participant_name:内部参会人名称
outside_participant_name:外部参会人名称
outside_participant_phone:外部参会人手机号码
message_notification:消息提醒时间
notification_method:通知方式
check_text:检查提示文本
"""
# 初始化通知文本为空字符串
notify_text = ""
# 从全局存储中获取webdriver实例
wd = GSTORE['wd']
name = self.name
conference_name, message_name, 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
# 在会议室列表搜索会议室
STEP(1, f"在会议室列表搜索:{conference_name}")
# 展开筛选下拉框
safe_click((By.XPATH, "//i[@class='el-collapse-item__arrow el-icon-arrow-right']"),wd)
sleep(1)
# 输入会议室名称,并点击【查询】按钮
safe_send_keys((By.XPATH, "//input[@placeholder='请输入会议室名称']"),conference_name,wd)
safe_click((By.XPATH, "//button[@type='button']//span[contains(text(),'查询')]"),wd)
sleep(1)
INFO("检查搜索结果")
# 获取搜索出的会议室名称
notify_text = elment_get_text((By.XPATH, "//span[@class='MeetingCityList_name']"),wd)
INFO(f"搜索结果为:{notify_text}")
CHECK_POINT("搜索结果是否正确", conference_name in notify_text)
# 点击【会议预定】按钮,进入会议预定界面
STEP(2, "点击【会议预定】按钮")
safe_click((By.XPATH, "//span[@class='MeetingCityList_t_btn']"),wd)
sleep(1)
INFO("检查页面标题是否正确")
# 获取页面标题
notify_text = elment_get_text((By.XPATH, "//div[@class='reserve_Title']"),wd)
INFO(f"页面标题为:{notify_text}")
CHECK_POINT("页面标题是否正确", "会议预定" in notify_text)
sleep(1)
# 在会议预定第一步界面进行数据填入
STEP(3,"会议第一步数据填写")
INFO(f"输入会议名称:{message_name},选择预约类型:{book_type},输入主持人:{host_name},输入会议内容:{message_content},选择会议开始时间:{book_start_time},选择会议结束时间:{book_end_time}")
# 输入会议名称
safe_send_keys((By.XPATH, "//input[@placeholder='请输入会议名称']"),message_name,wd)
# 判断预约类型
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)
sleep(2)
# # 输入议题名称
# safe_send_keys((By.XPATH, "//input[@placeholder='请输入会议议题']"),issue_name,wd)
# # 选择议题文件进行上传
# safe_click((By.XPATH, "//div[@class='topicsHandleButton uploadFile']"),wd)
# sleep(1)
# 将字符串转换为时间对象
start_time = datetime.strptime(book_start_time, time_format)
end_time = datetime.strptime(book_end_time, time_format)
# 如果需要将时间差转换为分钟数
time_diff_minutes = (end_time - start_time).total_seconds() / 60
INFO(f"时间差为:time_diff_minutes")
# 判断如果开始时间与结束时间相等,则不重复点击
if book_start_time == book_end_time:
INFO(f"开始时间与结束时间相等,选择时间块:{book_start_time}")
# 根据开始时间选择对应时间块,时间格式为:**:**
safe_click((By.XPATH, f"(//div[normalize-space()='{book_start_time}'])[1]"), wd)
elif book_start_time != book_end_time:
INFO(f"开始时间与结束时间不相等,选择时间块:{book_start_time},{book_end_time}")
# 根据开始时间选择对应时间块,时间格式为:**:**
safe_click((By.XPATH, f"(//div[normalize-space()='{book_start_time}'])[1]"), wd)
# 根据结束时间选择对应时间块,时间格式为:**:**
safe_click((By.XPATH, f"(//div[normalize-space()='{book_end_time}'])[1]"), wd)
sleep(2)
# 判断时间差是否大于最大预约时长1小时,即60分钟
if time_diff_minutes > 60:
INFO(f"时间差大于最大预约时长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}")
CHECK_POINT("超出预约时长提示是否正确", "最大预定时间 1 小时" in notify_text)
sleep(2)
# 不选时间点击【下一步】查看提示信息
INFO("不选时间点击【下一步】查看提示信息")
safe_click((By.XPATH, "//div[contains(text(),'下一步')]"),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}")
CHECK_POINT("未选时间提示是否正确", "请选择会议时间" in notify_text)
sleep(1)
# 重新选择时间,将字符串转换为时间对象
time_obj = datetime.strptime(book_end_time, time_format)
time_obj_minus_5_minutes = time_obj - timedelta(minutes=30)
# 将时间对象转换回字符串
book_end_time = time_obj_minus_5_minutes.strftime(time_format)
INFO(f"重新选择结束时间为:{book_end_time}")
# 根据开始时间选择对应时间块,时间格式为:**:**
safe_click((By.XPATH, f"(//div[normalize-space()='{book_start_time}'])[1]"), wd)
# 根据结束时间选择对应时间块,时间格式为:**:**
safe_click((By.XPATH, f"(//div[normalize-space()='{book_end_time}'])[1]"), wd)
sleep(2)
# 在会议预定第二步界面进行数据填入
STEP(4, "会议第二步数据填写")
# 点击【下一步】进入会议预定第二步界面
safe_click((By.XPATH, "//div[contains(text(),'下一步')]"),wd)
sleep(1)
# 根据参会人名称搜搜对应参会人
safe_send_keys((By.XPATH, "//input[@placeholder='账号/用户名']"),inside_participant_name,wd)
send_keyboard((By.XPATH, "//input[@placeholder='账号/用户名']"), wd)
sleep(1)
# 选择内部参会人
INFO(f"选择内部参会人:{inside_participant_name}")
safe_click((By.XPATH,"//tbody//tr//td//div//label//span//span"),wd)
# 获取已选的参会人名称
notify_text = elment_get_text((By.XPATH, f"//span[normalize-space()='{inside_participant_name}']"),wd)
INFO(f"已选择参会人:{notify_text}")
CHECK_POINT("内部参会人选择是否正确", inside_participant_name in 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}")
CHECK_POINT("弹窗标题是否正确", "添加外部参会人员" in 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}")
CHECK_POINT("提示信息是否正确", "添加成功" in notify_text)
# 点击【下一步】按钮
safe_click((By.XPATH,"//div[contains(text(),'下一步')]"),wd)
# 进入会议预约第三步进行填写
STEP(5, "会议第三步数据填写")
INFO("检查页面标题是否正确")
sleep(1)
# 获取页面标题
notify_text = elment_get_text((By.XPATH,"//h2[contains(text(),'消息提醒')]"),wd)
INFO(f"页面标题为:{notify_text}")
CHECK_POINT("页面标题是否正确", "消息提醒" in 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}")
# 判断消息提醒时间是否为全选
if message_notification == "全选":
# 点击【全选】按钮
safe_click((By.XPATH,"//div[@class='Reminds']//span[@class='el-checkbox__label'][contains(text(),'全选')]"),wd)
sleep(1)
else:
# 选择对应的消息提醒时间
safe_click((By.XPATH, f"//span[contains(text(),'{message_notification}')]"), wd)
sleep(1)
# 选择通知方式
INFO(f"选择通知方式:{notification_method}")
# if notification_method == "全选":
# 点击【全选】按钮
# safe_click((By.XPATH,"//div[@class='Sendout']//span[@class='el-checkbox__label'][contains(text(),'全选')]"),wd)
# else:
# 选择对应的通知方式
# safe_click((By.XPATH, f"//span[contains(text(),'{notification_method}')]"), wd)
# sleep(1)
# 点击【确定】按钮
STEP(6, "点击【确定】按钮")
safe_click((By.XPATH,"//div[contains(text(),'确定')]"),wd)
# 检查会议信息是否正确
STEP(7, "检查提示会议信息是否正确")
sleep(1)
INFO(
f"检查会议名称:{message_name},输入会议内容:{message_content}")
# 获取会议名称与会议内容
message_name_text = elment_get_text((By.XPATH,f"//div[contains(text(),'{message_name}')]"),wd)
message_content_text = elment_get_text((By.XPATH,f"//div[contains(text(),'{message_content}')]"),wd)
CHECK_POINT("提示信息是否正确", message_name_text in message_name and message_content_text in message_content)
# 点击最后【确定】按钮,预定成功后会跳转至已预定界面
STEP(8, "点击【确定】按钮")
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)
# CHECK_POINT("是否显示加载中", "提交数据中" in notify_text)
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}")
CHECK_POINT("预定成功提示是否正确", notify_text == check_text)
# 进行切换至会议室列表界面
# STEP(9, "清除会议数据")
# safe_send_keys((By.XPATH, "//input[@placeholder='输入关键字搜索']"), message_name, wd)
# send_keyboard((By.XPATH, "//input[@placeholder='输入关键字搜索']"), wd)
# sleep(2)
# # 判断会议类型
# if repetitive_cycle == '周期会议':
# INFO("点击【删除会议】按钮")
# # 点击【删除会议】按钮
# safe_click((By.CSS_SELECTOR,
# "tbody tr:nth-child(1) td:nth-child(8) div:nth-child(1) button:nth-child(2) span:nth-child(1)"),
# wd)
# sleep(5)
# INFO("点击【删除本场及以后周期会议】按钮")
# safe_click((By.XPATH, "//span[contains(text(),'删除本次及后续的周期会议')]"), wd)
# sleep(2)
# # 点击【确定】按钮
# safe_click((By.XPATH, "//div[contains(@aria-label,'提示')]//span[contains(text(),'确定')]"), wd)
# sleep(2)
#
# else:
# # 点击【删除会议】按钮
# safe_click((By.XPATH, "//span[contains(text(),'删除会议')]"), wd)
# sleep(2)
# # 点击【确定】按钮
# safe_click((By.XPATH,
# "//button[contains(@class,'el-button el-button--default el-button--small el-button--primary')]//span[contains(text(),'确定')]"),
# wd)
# sleep(2)
STEP(10, "跳转至会议室列表界面")
# 点击会议室列表导航栏
safe_click((By.XPATH, "//span[contains(text(),'会议室列表')]"), wd)
sleep(1)
INFO("检查界面标题是否为:会议室列表")
# 获取会议室列表界面的标题信息
notify_text = elment_get_text((By.XPATH, "//div[@class='header']//span[contains(text(),'会议室列表')]"), wd)
CHECK_POINT("界面标题是否正确", "会议室列表" in notify_text)