Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
X
xm-uitest-sow
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
xiamai-test
xm-uitest-sow
Commits
bc7dbb43
Commit
bc7dbb43
authored
Jun 18, 2021
by
linguangwei
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
登录-开课-结束课程-关闭客户端
parent
03c8c945
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
225 additions
and
53 deletions
+225
-53
.idea/inspectionProfiles/Project_Default.xml
+20
-0
.idea/workspace.xml
+0
-0
main.py
+2
-2
requirements.txt
+3
-0
src/framework/common.py
+105
-2
src/pageobject/basepage.py
+34
-2
src/pageobject/mainpage.py
+58
-45
src/testcase/testLoginPage.py
+3
-2
No files found.
.idea/inspectionProfiles/Project_Default.xml
0 → 100644
View file @
bc7dbb43
<component
name=
"InspectionProjectProfileManager"
>
<profile
version=
"1.0"
>
<option
name=
"myName"
value=
"Project Default"
/>
<inspection_tool
class=
"PyPep8NamingInspection"
enabled=
"true"
level=
"WEAK WARNING"
enabled_by_default=
"true"
>
<option
name=
"ignoredErrors"
>
<list>
<option
value=
"N806"
/>
</list>
</option>
</inspection_tool>
<inspection_tool
class=
"PyUnresolvedReferencesInspection"
enabled=
"true"
level=
"WARNING"
enabled_by_default=
"true"
>
<option
name=
"ignoredIdentifiers"
>
<list>
<option
value=
"requests.models.Response.__getitem__"
/>
</list>
</option>
</inspection_tool>
</profile>
</component>
\ No newline at end of file
.idea/workspace.xml
View file @
bc7dbb43
This diff is collapsed.
Click to expand it.
main.py
View file @
bc7dbb43
...
...
@@ -4,13 +4,13 @@ from src.framework.HTMLTestRunner import HTMLTestRunner
from
src.framework
import
common
from
src.testcase.testLoginPage
import
TestLoginPage
as
TLP
# from src.testcase.testHomePage import TestHomePage as TH
P
from
src.testcase.testMainPage
import
TestMainPage
as
TM
P
# from src.testcase.testWordPage import TestWordPage as TWP
if
__name__
==
'__main__'
:
testunit
=
unittest
.
TestSuite
()
testunit
.
addTest
(
TLP
(
'testLogin'
))
# testunit.addTests([THP('testHonors'), THP('testModifyPassword'), THP('testModifyInformation'), THP('testLogout'), THP('testWordTest
')])
testunit
.
addTests
([
TMP
(
'test_1_UnStartLive'
),
TMP
(
'test_2_StartLive'
),
TMP
(
'test_3_ReviewLive
'
)])
# testunit.addTests([TWP('testWordsEvaluation'), TWP('testWordReinforcement'), TWP('test_unit'), TWP('testOfflineDictation'), TWP('testPreview'), TWP('testShorthand'), TWP('testDictation'), TWP('testMemoryWrite'), TWP('testPostTest'), TWP('testReview'), TWP('testxiaoxiaole')])
# 定义报告输出路径
...
...
requirements.txt
View file @
bc7dbb43
selenium
==3.141.0
pytest
==6.2.4
Pillow
~=8.2.0
requests
~=2.25.1
\ No newline at end of file
src/framework/common.py
View file @
bc7dbb43
import
time
import
json
import
math
import
operator
import
os
import
random
import
string
import
time
from
functools
import
reduce
import
requests
from
PIL
import
Image
def
year_to_minute
():
return
time
.
strftime
(
'
%
Y
%
m
%
d
%
H
%
M
%
S'
,
time
.
localtime
(
time
.
time
()))
def
now_time
():
return
int
(
time
.
time
()
*
1000
)
def
year_to_day
():
return
time
.
strftime
(
'
%
Y
%
m
%
d'
,
time
.
localtime
(
time
.
time
()))
return
time
.
strftime
(
'
%
Y
-
%
m-
%
d'
,
time
.
localtime
(
time
.
time
()))
def
file_abspath
():
return
os
.
path
.
abspath
(
__file__
)
.
split
(
'src'
)[
0
]
def
screenshot_path
():
screenshot_file
=
file_abspath
()
+
"/screenshots/"
+
year_to_day
()
if
not
os
.
path
.
exists
(
screenshot_file
):
os
.
mkdir
(
screenshot_file
)
return
screenshot_file
# 比较图片差异度,result越大,差异度越大,result=0,图片相同
def
compare_pictures
(
pic1
,
pic2
):
image1
=
Image
.
open
(
pic1
)
image2
=
Image
.
open
(
pic2
)
h1
=
image1
.
histogram
()
h2
=
image2
.
histogram
()
result
=
math
.
sqrt
(
reduce
(
operator
.
add
,
list
(
map
(
lambda
a
,
b
:
(
a
-
b
)
**
2
,
h1
,
h2
)))
/
len
(
h1
))
return
result
# 获取登录token
def
get_token
():
headers
=
{
"Content-Type"
:
"application/json; charset=UTF-8"
,
"User-Agent"
:
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/91.0.4472.77 Safari/537.36"
}
params
=
{
"phone"
:
"13777867342"
,
"authCode"
:
"0000"
,
"appTermEnum"
:
"XIAOMAI_CLOUD_CLASS_PC_WEB_ADMIN"
}
data
=
json
.
dumps
(
params
)
url
=
"https://gateway.xiaomai5.com/hades/anon/hades/login?storeId=null&token=null&storeUserId=null&userId=null"
r
=
requests
.
post
(
url
=
url
,
data
=
data
,
headers
=
headers
)
try
:
xmtoken
=
r
.
json
()[
"result"
][
"xmToken"
]
except
Exception
as
e
:
return
r
.
json
()[
"message"
]
return
xmtoken
# 创建一个直播课,返回课程id和课程名称
def
create_a_live
(
start_time
,
start_time2
=
None
):
xmtoken
=
get_token
()
while
xmtoken
==
"登录过频繁"
:
# 休息5s是因为可能会登录频繁
time
.
sleep
(
5
)
xmtoken
=
get_token
()
print
(
xmtoken
)
dt
=
year_to_day
()
+
' 00:00:00'
calendarTime
=
int
(
time
.
mktime
(
time
.
strptime
(
dt
,
"
%
Y-
%
m-
%
d
%
H:
%
M:
%
S"
)))
*
1000
startTime
=
now_time
()
+
start_time
*
60
*
1000
endTime
=
calendarTime
+
23
*
60
*
60
*
1000
# endTime = startTime + 5*60*1000
courseName
=
''
.
join
(
random
.
sample
(
string
.
ascii_letters
+
string
.
digits
,
8
))
courseName2
=
''
.
join
(
random
.
sample
(
string
.
ascii_letters
+
string
.
digits
,
8
))
url
=
"https://gateway.xiaomai5.com/hades/public/courseCloud/createLiveCloudCourse?storeId=1211601438838495999"
\
"&token={}&storeUserId=1394257952460828673&userId=1394908740376522754"
.
format
(
xmtoken
)
params
=
{
"adminIds"
:
[],
"calendarTime"
:
[
calendarTime
],
"categoryId"
:
"1386892090935164929"
,
"endTime"
:
endTime
,
"needRecord"
:
"YES"
,
"startTime"
:
startTime
,
"courseName"
:
courseName
,
"storeId"
:
"1211601438838495999"
,
"teacherId"
:
"1394908740376522754"
,
"whetherVisitorsJoin"
:
"NO"
,
"scheduleMediaRequests"
:
[],
"operatorId"
:
"1394908740376522754"
}
data
=
json
.
dumps
(
params
)
headers
=
{
"Content-Type"
:
"application/json; charset=UTF-8"
,
"User-Agent"
:
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/91.0.4472.77 Safari/537.36"
,
"storeId"
:
"1211601438838495999"
,
"storeUserId"
:
"1394257952460828673"
,
"xmtoken"
:
xmtoken
,
"userId"
:
"1394908740376522754"
,
"product"
:
"xmCloudClass"
}
r
=
requests
.
post
(
url
=
url
,
data
=
data
,
headers
=
headers
)
if
start_time2
is
not
None
:
time
.
sleep
(
2
)
startTime2
=
now_time
()
+
start_time2
*
60
*
1000
params2
=
{
"adminIds"
:
[],
"calendarTime"
:
[
calendarTime
],
"categoryId"
:
"1386892090935164929"
,
"endTime"
:
endTime
,
"needRecord"
:
"YES"
,
"startTime"
:
startTime2
,
"courseName"
:
courseName2
,
"storeId"
:
"1211601438838495999"
,
"teacherId"
:
"1394908740376522754"
,
"whetherVisitorsJoin"
:
"NO"
,
"scheduleMediaRequests"
:
[],
"operatorId"
:
"1394908740376522754"
}
data2
=
json
.
dumps
(
params2
)
r2
=
requests
.
post
(
url
=
url
,
data
=
data2
,
headers
=
headers
)
try
:
# 校验result中是否会返回课程id
assert
r
.
json
()[
"result"
]
!=
''
assert
r2
.
json
()[
"result"
]
!=
''
list1
=
[
courseName
,
courseName2
]
return
list1
except
Exception
as
e
:
print
(
e
.
args
)
else
:
try
:
# 校验result中是否会返回课程id
assert
r
.
json
()[
"result"
]
!=
''
return
courseName
except
Exception
as
e
:
print
(
e
.
args
)
src/pageobject/basepage.py
View file @
bc7dbb43
from
time
import
sleep
from
config
import
readConfig
# pages基类
from
selenium.webdriver.common.action_chains
import
ActionChains
from
selenium.webdriver.common.keys
import
Keys
from
selenium.common.exceptions
import
NoSuchElementException
from
selenium.webdriver.common.by
import
By
class
Page
(
object
):
...
...
@@ -21,6 +26,10 @@ class Page(object):
def
input_text
(
self
,
loc
,
text
):
self
.
find_element
(
*
loc
)
.
send_keys
(
text
)
# 获取元素文本
def
get_text
(
self
,
loc
):
return
self
.
driver
.
find_element
(
*
loc
)
.
text
# 点击框点击
def
click
(
self
,
loc
):
self
.
find_element
(
*
loc
)
.
click
()
...
...
@@ -60,9 +69,13 @@ class Page(object):
def
sleep
(
self
,
seconds
):
return
sleep
(
seconds
)
# 键盘down
def
keys_down
(
self
):
ActionChains
(
self
.
driver
)
.
key_down
(
Keys
.
DOWN
)
.
key_up
(
Keys
.
DOWN
)
.
perform
()
# 屏幕最大化
def
max
(
self
):
self
.
driver
.
maximize_window
()
def
max
(
self
,
*
loc
):
self
.
driver
.
find_element
(
*
loc
)
.
click
()
# 判断元素是否存在于页面
def
ifElementExist
(
self
,
loc
):
...
...
@@ -85,3 +98,22 @@ class Page(object):
# 关闭窗口
def
close
(
self
,
loc
,
num
):
self
.
find_elements
(
*
loc
)[
num
]
.
click
()
def
save_screenshot
(
self
,
filename
):
self
.
driver
.
save_screenshot
(
filename
)
def
login
(
self
):
driver
=
self
.
driver
login_page
=
Page
(
driver
=
driver
)
# 手机号登录按钮
phone_login
=
(
By
.
ID
,
"rc-tabs-0-tab-2"
)
# 账号输入框
account_input
=
(
By
.
ID
,
"xmphone"
)
# 密码输入框
password_input
=
(
By
.
ID
,
"xmpwd"
)
# 登录按钮
login_button
=
(
By
.
CLASS_NAME
,
"submit"
)
login_page
.
click
(
phone_login
)
login_page
.
input_text
(
account_input
,
readConfig
.
test_account
())
login_page
.
input_text
(
password_input
,
readConfig
.
test_password
())
login_page
.
click
(
login_button
)
src/pageobject/mainpage.py
View file @
bc7dbb43
...
...
@@ -3,61 +3,75 @@ from selenium.webdriver.common.by import By
# 主页面
class
Home
Page
(
LoginPage
):
class
Main
Page
(
LoginPage
):
# 元素集
# '未完成任务'按钮
incomplete
=
(
By
.
XPATH
,
"//div[text()='未完成任务']"
)
# '未完成任务'按钮
completed
=
(
By
.
XPATH
,
"//div[text()='已完成任务']"
)
# 荣誉榜按钮
honors
=
(
By
.
XPATH
,
"//span[text()='荣誉榜']"
)
# 修改密码按钮
modifypassword
=
(
By
.
XPATH
,
"//span[text()='修改密码']"
)
# 修改信息按钮
modifyinformation
=
(
By
.
XPATH
,
"//span[text()='修改信息']"
)
# 退出系统按钮
logout
=
(
By
.
XPATH
,
"//span[text()='退出系统']"
)
# 单词量测试按钮
wordtest
=
(
By
.
XPATH
,
"//div[text()='单词量测试']"
)
# "今日"按钮
today_btn
=
(
By
.
CLASS_NAME
,
"today"
)
# "月份"按钮
month_btn
=
(
By
.
CLASS_NAME
,
"month"
)
# "最小化"按钮
min_btn
=
(
By
.
XPATH
,
"//div[@class='iconBaner']//span[1]"
)
# "刷新"按钮
refresh_btn
=
(
By
.
XPATH
,
"//div[@class='iconBaner']//span[2]"
)
# "关闭"按钮
close_btn
=
(
By
.
XPATH
,
"//div[@class='iconBaner']//span[3]"
)
# 获取直播列表
live_list
=
(
By
.
CLASS_NAME
,
"list-content"
)
# "进入直播间"按钮 format里面的参数还是要继续修改,先创建课程,再通过课程名称来查看进入直播间按钮
in_live_btn
=
(
By
.
XPATH
,
"""//div[text()={{coursename}}]/..//button[@class="ant-btn ant-btn-primary"]"""
.
format
())
# 开始直播按钮
start_live_btn
=
(
By
.
XPATH
,
"""//span[text()="是"]"""
)
# 结束直播按钮
stop_live_btn
=
(
By
.
XPATH
,
"""//span[text()="结束直播"]"""
)
# 二次确认直播按钮
cancel_stop_live_btn
=
(
By
.
XPATH
,
"""//span[text()="取 消"]"""
)
# 验证元素
# 荣誉榜-总排行
total_tanking
=
(
By
.
XPATH
,
"//li[text()='总排行']"
)
# 修改密码-确认密码
confirm_password
=
(
By
.
CLASS_NAME
,
"title"
)
# 修改信息-姓名
name
=
(
By
.
CLASS_NAME
,
"title.short"
)
# 单词量测试-学段测试
stage_test
=
(
By
.
XPATH
,
"//div[text()='学段测试']"
)
# 开启/关闭摄像头按钮
camera_btn
=
(
By
.
XPATH
,
"//div[@class='camera']/span"
)
def
__init__
(
self
,
driver
):
LoginPage
.
__init__
(
self
,
driver
)
# 点击'
未完成任务
'
def
click_
incomplete
(
self
):
self
.
click
(
self
.
incomplete
)
# 点击'
今日
'
def
click_
today_btn
(
self
):
self
.
click
(
self
.
today_btn
)
# 点击'
已完成任务
'
def
click_
completed
(
self
):
self
.
click
(
self
.
completed
)
# 点击'
月份
'
def
click_
month_btn
(
self
):
self
.
click
(
self
.
month_btn
)
# 点击'
荣誉榜
'
def
click_
honors
(
self
):
self
.
click
(
self
.
honors
)
# 点击'
最小化
'
def
click_
min_btn
(
self
):
self
.
click
(
self
.
min_btn
)
# 点击'
修改密码
'
def
click_
modifypassword
(
self
):
self
.
click
(
self
.
modifypassword
)
# 点击'
刷新
'
def
click_
refresh_btn
(
self
):
self
.
click
(
self
.
refresh_btn
)
# 点击'
修改信息
'
def
click_
modifyinformatio
n
(
self
):
self
.
click
(
self
.
modifyinformatio
n
)
# 点击'
关闭
'
def
click_
close_bt
n
(
self
):
self
.
click
(
self
.
close_bt
n
)
# 点击'退出系统'
def
click_logout
(
self
):
self
.
click
(
self
.
logout
)
# 点击'进入直播间'
def
click_in_live_btn
(
self
,
coursename
):
self
.
in_live_btn
=
(
By
.
XPATH
,
"""//div[text()="{}"]/..//button[@class="ant-btn ant-btn-primary"]"""
.
format
(
coursename
))
self
.
click
(
self
.
in_live_btn
)
# 点击'单词量测试'
def
click_wordtest
(
self
):
self
.
click
(
self
.
wordtest
)
\ No newline at end of file
def
click_camera_btn
(
self
):
self
.
click
(
self
.
camera_btn
)
def
start_live
(
self
):
self
.
click
(
self
.
start_live_btn
)
def
stop_live
(
self
):
self
.
click
(
self
.
stop_live_btn
)
def
get_live_name
(
self
):
self
.
keys_down
()
# 获取按钮文本
def
get_btn_text
(
self
,
coursename
):
self
.
in_live_btn
=
(
By
.
XPATH
,
"""//div[text()="{}"]/..//button[@class="ant-btn"]"""
.
format
(
coursename
))
return
self
.
get_text
(
self
.
in_live_btn
)
src/testcase/testLoginPage.py
View file @
bc7dbb43
from
src.pageobject.loginpage
import
LoginPage
from
src.framework.logger
import
Logger
from
src.framework.appDriver
import
get_app_driver
from
config
import
readConfig
from
commom.appDriver
import
get_app_driver
import
unittest
...
...
@@ -14,7 +14,7 @@ class TestLoginPage(unittest.TestCase):
def
setUp
(
self
)
->
None
:
print
(
11111
)
# 指定
chrome的webdriver路径
# 指定
Pc端的本地路径,在/config/config.ini配置
self
.
driver
=
get_app_driver
(
self
.
cloud_class_location
)
def
tearDown
(
self
)
->
None
:
...
...
@@ -29,6 +29,7 @@ class TestLoginPage(unittest.TestCase):
login_page
.
input_password
(
password
=
self
.
password
)
login_page
.
click_login
()
login_page
.
sleep
(
1
)
# 校验是否存在店铺名称的元素
self
.
assertTrue
(
login_page
.
ifElementExist
(
login_page
.
store_name
))
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment