Commit 0c277885 authored by xiao-hesheng's avatar xiao-hesheng
Browse files

Signed-off-by: xiao-hesheng <xhs89@sina.com>

parent 26c6f206
Pipeline #3481 failed with stages
in 25 seconds
"course":
- health
- select * from health.course where status=2 and type=0 ORDER BY create_time DESC LIMIT 10;
"prc_prom_price":
- cloud
- select * from access_log where id = %s;
\ No newline at end of file
# 存储业务sql
"select_patient":
- medical
- SELECT relation_id,name,gender,id FROM `patient` where enc_user_id=%s and deleted=0;
"queryPatientList_url": "/newapi/router/medical/patient/queryPatientList"
"enc_user_id": "u589639224866"
"queryPatientList_querystring": ""
"rtn_msg": "请求成功"
"relationId_msg": "验证就诊人与本人关系"
"name_msg": "验证就诊人姓名"
"gender_msg": "验证就诊人性别"
# 存储业务sql
"select_patient":
- medical
- SELECT relation_id,name,gender,id FROM `patient` where enc_user_id=%s and deleted=0;
# -*- encoding=utf-8 -*-
import os
import sys
import requests
import math
import re
import time
from bs4 import BeautifulSoup
from random import shuffle
import datetime
import pypinyin
def exchange(word):
"""
中文转拼音
:param word:
:return:
"""
s = ''
for i in pypinyin.pinyin(word, style=pypinyin.NORMAL):
s += ''.join(i)
return s
def get_dir_exist(path, div_num):
"""
判断报告文件夹是否存在
"""
for i in range(div_num):
test_path = path + os.sep + 'report_' + str(i+1)
if not os.path.isdir(test_path):
return False
return True
def merge_report(div_num, report_path):
"""
合并报告
"""
total_cases = 0
succ_cases = 0
max_time = 0.0
time_str = ''
summary_r = open(report_path + os.sep + 'summary.html', 'r', encoding='utf-8')
lines = summary_r.readlines()[:43]
summary_r.close()
summary_w = open(report_path + os.sep + 'summary.html', 'w', encoding='utf-8')
for i in range(div_num):
file = report_path + os.sep + 'report_' + str(i+1) + os.sep + 'summary.html'
print(file)
htmlfile = open(file, 'r', encoding='utf-8')
htmlhandle = htmlfile.read()
soup = BeautifulSoup(htmlhandle, 'html.parser')
tables = soup.find_all("table")
#print(tables)
#第一个table存的是概要,第二个table存的是具体case。先读第一个表
tab = tables[0]
tr = tab.findAll('tr')[1]
tds = tr.findAll('td')
total_cases += int(tds[0].getText())
succ_cases += int(tds[1].getText())
minite = int(tds[2].getText().split('分')[0])
second = int(tds[2].getText().split('分')[1].split('秒')[0])
number = minite + second/60
#print(number)
if number > max_time:
max_time = number
time_str = tds[2].getText()
#再读第二个表
tab = tables[1]
trs = tab.findAll('tr')
print(len(trs))
for i in range(len(trs)):
if i == 0:
continue
tds = trs[i].findAll('td')
case_name = tds[0].getText()
status = tds[1].getText()
run_time = tds[2].getText()
if status == '成功':
html = '''
<tr width="600">
<td class="details-col-elapsed">%s</td>
<td class="success">%s</td>
<td class="details-col-elapsed">%s</td>
</tr>''' % (case_name, status, run_time)
else:
html = '''
<tr width="600">
<td class="details-col-elapsed">%s</td>
<td class="fail">%s</td>
<td class="details-col-elapsed">%s</td>
</tr>''' % (case_name, status, run_time)
lines.append(html)
#print(html)
pass_rate = round(succ_cases*100/total_cases, 2)
summary = '''
<!--<div><h2>Test Statistics</h2></div>-->
<table width="800">
<caption><ul><li>测试概要</li></ul></caption>
<tr width="600">
<th width="300" class='details-col-msg'>用例总数</th>
<th class='details-col-msg'>成功数</th>
<th class='details-col-msg'>运行用时</th>
<th class='details-col-msg'>成功率</th>
</tr>
<tr width="600">
<td class='details-col-elapsed'>%s</td>
<td class='details-col-elapsed'>%s</td>
<td class='details-col-elapsed'>%s</td>
<td class="details-col-elapsed">%s</td>
</tr>
</table>
</table>
<!--<div><h2>Test detail</h2></div>-->
<table width="800">
<caption><ul><li>测试列表</li></ul></caption>
<tr width="600">
<th width="300" class='details-col-msg'>用例名称</th>
<th class='details-col-msg'>执行结果</th>
<th class='details-col-msg'>执行时间(秒)</th>
</tr>
''' % (total_cases, succ_cases, time_str, str(pass_rate))
summary_w.write(summary)
for line in lines:
summary_w.write(line)
end_html = '''
</table>
<div><h2></h2></div>
</div>
</body>
</html>'''
summary_w.write(end_html)
summary_w.close()
time_str = time_str.replace('分', 'm').replace('秒', 's')
return total_cases, succ_cases, time_str, pass_rate
def get_mess_from_report(report_path):
"""
从报告中获取运行case数
:return:
"""
htmlfile = open(report_path + os.sep + 'summary.html', 'r', encoding='utf-8')
htmlhandle = htmlfile.read()
soup = BeautifulSoup(htmlhandle, 'html.parser')
tables = soup.find_all("table")
# print(tables)
# 第一个table存的是概要,第二个table存的是具体case。先读第一个表
tab = tables[0]
tr = tab.findAll('tr')[1]
tds = tr.findAll('td')
total_cases = int(tds[0].getText())
succ_cases = int(tds[1].getText())
time_str = tds[2].getText()
time_str = time_str.replace('分', 'm').replace('秒', 's')
pass_rate = round(succ_cases * 100 / total_cases, 2)
htmlfile.close()
return total_cases, succ_cases, time_str, pass_rate
def get(url):
try:
return requests.get(url)
except requests.exceptions.ConnectionError:
print('ConnectionError -- please wait 3 seconds')
time.sleep(1)
except requests.exceptions.ChunkedEncodingError:
print('ChunkedEncodingError -- please wait 3 seconds')
time.sleep(1)
except:
print('Unfortunitely -- An Unknow Error Happened, Please wait 3 seconds')
time.sleep(1)
def call_back_atms(runenv, job_name, build_num, total, rate, run_time, pool_name, build_user):
"""
回传数据到atms
:return:
"""
if runenv == 'autotestpreid':
runenv_b = 1
elif runenv == 'autotestsitid':
runenv_b = 2
else:
runenv_b = 0
url = "http://atms.baobaoshu.com/atms/rest/api/getJobResult?jobName=" + job_name + "&runenv=" + str(
runenv_b) + "&buildNumber=" + str(build_num) + "&allSum=" + str(total) + "&passRate=" + str(
rate) + "&execTime=" + run_time + "&poolName=" + pool_name + "&buildUser=" + build_user + "&p0Sum=0&p1Sum=0&p2Sum=0"
print(url)
response = get(url)
print("回调atms返回结果")
print(response.content.decode())
def call_back_cloud(runenv, pool_name, build_num, start, end, job_url, build_user, rate, oldrev, newrev):
"""
回传到云平台
:return:
"""
if rate == 100.0:
status = 'success'
else:
status = 'fail'
job_url = job_url + str(build_num) + '/artifact/report/summary.html'
url = "http://cloud.baobaoshu.com/cloud/buildautotest?type=" + \
runenv + "&buildid=" + str(build_num) + "&pool=" + pool_name + \
"&codeversion=" + str(newrev) + "&lastcversion=" + str(oldrev) + \
"&starttime=" + str(start) + "&endtime=" + str(end) + "&status=" + status + \
"&url=" + str(job_url) + "&autopassrate=" + str(rate) + "&user=" + str(build_user)
print(url)
response = get(url)
print("回调云平台返回结果")
print(response.content.decode())
def call_back_muse(deployid, cbtoken, build_user, pass_rate, job_url, build_num):
"""
回调muse
:return:
"""
print("call back muse")
result = 'Fail'
if deployid != 'deployid' and cbtoken != 'cbtoken' and build_user == 'SYSTEM':
if pass_rate == 100.0:
result = 'Success'
url = 'http://muse.baobaoshu.com/apiv1/deployment/ci-callback/'
data = {'deployid': deployid, 'job_url': job_url, 'build_number': build_num, 'result': result, 'cbtoken': cbtoken}
r = requests.post(url, data)
print(data)
print(r.content.decode())
else:
print('非远程触发')
pass
if __name__ == '__main__':
start = datetime.datetime.now().strftime('%Y%m%d%H%M%S')
print('start')
case_path = os.path.abspath(".") + os.sep + 'air_case'
report_path = os.path.abspath(".") + os.sep + 'report'
# pool名
pool_name = sys.argv[1]
runenv = sys.argv[2]
job_name = sys.argv[3]
build_num = sys.argv[4]
job_url = sys.argv[5]
build_user = exchange(sys.argv[6])
oldrev = sys.argv[7]
newrev = sys.argv[8]
Jobs = ['AutoTest_Pregnancy_First', 'AutoTest_Pregnancy_Personal', 'AutoTest_Pregnancy_Community', \
'AutoTest_Pregnancy_Contents', 'AutoTest_Pregnancy_Tools/']
for i in range(5):
cmd = 'rd /s /q report\\report_' + str(i+1)
os.system(cmd)
url = 'http://192.168.24.100:8080/view/Tools/job/' + Jobs[i] + '/buildWithParameters?token=123456'
print(url)
requests.get(url)
# 等待1分钟
time.sleep(2400)
# 判断报告传输是否完成
while True:
is_done = get_dir_exist(report_path, 5)
if is_done:
total_cases, succ_cases, run_time, pass_rate = merge_report(5, report_path)
break
else:
time.sleep(5)
end = datetime.datetime.now().strftime('%Y%m%d%H%M%S')
# 回传数据到muse
#call_back_muse(deployid, cbtoken, build_user, pass_rate, job_url, build_num)
# 回传数据到atms
call_back_atms(runenv, job_name, build_num, total_cases, pass_rate, run_time, pool_name, build_user)
# 回传到云平台
call_back_cloud(runenv, pool_name, build_num, start, end, job_url, build_user, pass_rate, oldrev, newrev)
if pass_rate != 100.0:
sys.exit(1)
File added
项目结构:
自动化用例的工程目录
----common 存放公共方法
----air_case 存放用例case
----templates 存在模板报告
----report 存放case执行总报告及各用例报告
----log 存放case执行日志
----data 存放数据
runner.py case执行调度入口
总工程执行方式:
python3 runner.py 参数1 参数2 参数3 参数4 参数5
参数1: 设备id(多个用逗号分隔)
参数2:选择运行模式,s, m, d
s-> single 单设备运行,m-> multi 多设备运行(测兼容性相关,每个设备上都执行要执行的case)、d-> distribute多设备分布式运行(将case分布到不同的设备上跑,节省耗时)
参数3: case执行类型,all表示执行所有,choose表示选择性执行, tag表示按case级别执行任务
参数4: 与第二个参数对应,如果参数2是all,参数3可传all(非空值都行),参数2是choose, 参数3传要执行的case名称,多个case逗号分隔,
参数2是tag,参数3传tag名,多个tag用逗号分割,如:P0,P1
参数5: 设置日志级别,可选参数 WARN、DEBUG、INFO
实例1: 单设备跑所有的case及埋点,同时设置日志级别为DEBUG:
python3 runner.py 60fbe8cc s all all DEBUG
实例2:多设备跑部分case,同时设置日志级别为WARN
python3 runner.py 60fbe8cc,b5384901 m choose demo WARN
实例3:
单设备跑P0的case
python3 runner.py 60fbe8cc s tag P0 DEBUG
环境相关问题:
1、判断手机是否是锁屏态时需要用到adb,所以要保证我们的环境变量里有adb。
linux环境装完adb需要在环境变量里配置一下。
python也需要配置环境变量,配置如下:
vim ~/.bash_profile 加上
export PYTHON3=/usr/local/bin/
export ADB=/Applications/AirtestIDE.app/Contents/MacOS/airtest/core/android/static/adb/mac/
export PATH=$PATH:$PATHON3:$ADB
另外在终端里配置一下,使环境变量一直生效,不需要source
终端是zsh的话,加载的是 ~/.zshrc文件
vim ~/.zshrc 最后,增加一行:source ~/.bash_profile
windows环境可按windows设置环境变量的方式设置。
case相关问题:
1、如果case要分tag,可在写case的时候在代码里加上注释 case_tag:P0,checkList
当选择按tag去跑用例,我们会按关键字case_tag去获取对应case的级别,多个tag 逗号分隔
.hljs{display:block;padding:.5em;background:#23241f}.hljs,.hljs-tag,.css .hljs-rules,.css .hljs-value,.css .hljs-function .hljs-preprocessor,.hljs-pragma{color:#f8f8f2}.hljs-strongemphasis,.hljs-strong,.hljs-emphasis{color:#a8a8a2}.hljs-bullet,.hljs-blockquote,.hljs-horizontal_rule,.hljs-number,.hljs-regexp,.alias .hljs-keyword,.hljs-literal,.hljs-hexcolor{color:#ae81ff}.hljs-tag .hljs-value,.hljs-code,.hljs-title,.css .hljs-class,.hljs-class .hljs-title:last-child{color:#a6e22e}.hljs-link_url{font-size:80%}.hljs-strong,.hljs-strongemphasis{font-weight:bold}.hljs-emphasis,.hljs-strongemphasis,.hljs-class .hljs-title:last-child{font-style:italic}.hljs-keyword,.hljs-function,.hljs-change,.hljs-winutils,.hljs-flow,.lisp .hljs-title,.clojure .hljs-built_in,.nginx .hljs-title,.tex .hljs-special,.hljs-header,.hljs-attribute,.hljs-symbol,.hljs-symbol .hljs-string,.hljs-tag .hljs-title,.hljs-value,.alias .hljs-keyword:first-child,.css .hljs-tag,.css .unit,.css .hljs-important{color:#f92672}.hljs-function .hljs-keyword,.hljs-class .hljs-keyword:first-child,.hljs-constant,.css .hljs-attribute{color:#66d9ef}.hljs-variable,.hljs-params,.hljs-class .hljs-title{color:#f8f8f2}.hljs-string,.css .hljs-id,.hljs-subst,.haskell .hljs-type,.ruby .hljs-class .hljs-parent,.hljs-built_in,.sql .hljs-aggregate,.django .hljs-template_tag,.django .hljs-variable,.smalltalk .hljs-class,.django .hljs-filter .hljs-argument,.smalltalk .hljs-localvars,.smalltalk .hljs-array,.hljs-attr_selector,.hljs-pseudo,.hljs-addition,.hljs-stream,.hljs-envvar,.apache .hljs-tag,.apache .hljs-cbracket,.tex .hljs-command,.hljs-prompt,.hljs-link_label,.hljs-link_url{color:#e6db74}.hljs-comment,.hljs-javadoc,.java .hljs-annotation,.python .hljs-decorator,.hljs-template_comment,.hljs-pi,.hljs-doctype,.hljs-deletion,.hljs-shebang,.apache .hljs-sqbracket,.tex .hljs-formula{color:#75715e}.coffeescript .javascript,.javascript .xml,.tex .hljs-formula,.xml .javascript,.xml .vbscript,.xml .css,.xml .hljs-cdata,.xml .php,.php .xml{opacity:.5}
\ No newline at end of file
@charset "utf-8";
* {
padding: 0;
margin: 0;
}
html{
height: 100%;
}
body{
background: linear-gradient(#0A0011, #0C0B1F, #101628, #151D2F, #11182A, #150D21, #0A0011);
color: rgb(237,237,237);
font-size: 14px;
height: 100%;
position: relative;
}
.container-fluid{
margin: auto;
padding-right: 100px;
padding-left: 100px;
margin-bottom: 220px;
min-width: 960px;
min-height: calc(100% - 222px);
position: relative;
}
#back_multi .back {
position: fixed;
left: 20px;
top: 50px;
width: 50px;
height: 50px;
display: block;
border: solid 1px #2f4682;
border-radius: 40px;
}
#back_multi .back:hover {
background: #223159;
}
#back_multi .back img {
width: 25px;
margin-top: 12px;
margin-left: 12px;
}
h2.empty-report{
text-align: center;
margin-bottom: 60px;
margin-top: 30px;
}
.title{
font-size: 32px;
text-align: center;
padding-top: 50px;
}
.info-title{
font-size: 20px;
margin-bottom: 20px
}
.summary{
margin: 30px 0;
background: #121c34;
padding-top: 30px;
padding-left: 30px;
}
.summary .show-vertical, .summary .info3, .summary .show-horizontal .info{
width: 48%;
display: inline-block
}
.summary .show-horizontal .info2{
/* border-left: dashed 1px rgb(102,102,102); */
}
.summary .info{
line-height: 18px;
}
.summary .info3{
/* border-left: dashed 1px rgb(102,102,102); */
padding-left: 50px;
min-height: 260px;
vertical-align: top;
width: calc(48% - 50px);
}
.summary .info-left, .summary .info-right{
display: inline-block;
}
.summary .info-left{
width: 60px;
height: 100%;
vertical-align: top;
}
.summary .info-right {
width: calc(100% - 80px);
}
.summary .info-title .green, .summary .info-title .red{
color: rgb(184,233,134);
font-size: 16px;
margin-left: 48px;
display: inline-block;
}
.summary .info-title .red{
color: #fd5a3e;
}
.summary .info-content .info-sub{
display: inline-block;
margin-right: 30px;
}
.summary .info-toal{
margin: 18px 0 35px 0
}
.summary .info-toal>div{
display: inline-block;
height: 30px;
min-width: 30%;
}
.summary .info-toal .info-step, .summary .info-toal .info-console{
margin-right: 100px;
}
.summary .info-toal .info-console img#show-console {
width: 25px;
margin-left: 10px;
vertical-align: middle;
}
.summary .info-toal .info-console img#show-console:hover{
content: url(../image/console_hover.svg);
}
.summary .info-toal .info-value{
color: rgb(74,144,226);
font-size: 18px;
padding-left: 5px;
}
.summary .info-toal .info-value a{
color: rgb(74,144,226);
}
.summary .info-toal .info-value img{
margin-left: 10px;
width: 15px;
}
.summary .info-execute{
line-height: 18px;
margin: 20px 0;
cursor: context-menu;
position: relative;
}
.summary .info-execute #copy_path{
display: inline-block;
margin-left: 10px;
width: 20px;
vertical-align: bottom;
cursor: context-menu;
opacity: 0.6;
}
.summary .info-execute #copy_path:hover{
opacity: 1;
}
.summary .circle-img{
background: rgb(216,216,216);
width: 18px;
height: 18px;
float: left;
border-radius: 10px;
margin-right: 10px;
}
.summary .info-execute .info-name{
line-height: 18px;
}
.summary .airdesc.long .show-more{
content: '';
height: 25px;
width: 25px;
display: block;
background: url(../image/less.svg) no-repeat;
background-size: contain;
margin-left: 50px;
opacity: 0.5;
position: absolute;
}
.summary .airdesc.collapse .show-more{
display: block;
transform: rotate(180deg);
}
.summary .airdesc {
padding-bottom: 30px;
position: relative;
}
.summary .airdesc .desc-content{
height: auto;
overflow-y: hidden;
line-height: 24px;
font-size: 12px;
white-space: pre-wrap;
word-break: break-word;
}
.summary .airdesc.collapse .desc-content{
height: 160px;
}
.gallery{
margin-bottom: 30px;
}
.gallery .info-title{
margin-bottom: 10px;
}
.gallery .content{
background: rgb(18,28,52);
overflow-x: scroll;
white-space: nowrap;
background: #121c34;
padding-top: 20px;
}
.gallery .thumbnail {
display: inline-block;
border: solid 1px transparent;
}
.gallery .thumbnail.active {
border: solid 1px rgb(74,144,226);
}
.gallery .thumbnail img{
max-width: 120px;
max-height: 130px;
}
.gallery .thumbnail .time{
text-align: center;
font-size: 12px;
margin: 3px 0;
}
.step-list .no-steps{
text-align: center;
}
.step-list .content{
background: rgb(18,28,52)
}
#device{
display: none;
flex-wrap: wrap;
-ms-flex-wrap: wrap;
padding: 40px 0 30px 80px;
background: #121c34;
margin-bottom: 49px;
}
#device.show{
display: -ms-flexbox;
display: flex;
justify-content: flex-start;
}
#device .info{
width: 48%;
line-height: 30px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
#device .info.connect{
position: relative;
padding-right: 30px;
}
#device .info .copy_device{
content: "";
width: 18px;
height: 18px;
background: url(../image/copy.svg) no-repeat;
background-size: contain;
position: absolute;
right: 4px;
top: 3px;
opacity: 0.6;
}
#device .info .copy_device:hover{
opacity: 1;
}
#device .info span:first-child{
margin-right: 10px;
}
.steps-head {
position: relative;
background: rgb(22,34,62);
line-height: 40px;
}
.head-left {
padding-left: 20px;
}
.steps-head .order{
width: 100px;
text-align: center;
display: inline-block;
cursor: context-menu;
position: relative;
}
.steps-head .order::after{
content: "";
width: 16px;
height: 16px;
display: inline-block;
margin-left: 7px;
vertical-align: middle;
}
.steps-head .order:hover::after{
background: url(../image/order.svg);
}
.head-right{
position: absolute;
top: 0;
right: 0;
}
.head-right .filters{
margin-right: 20px;
margin-left: 10px;
}
.head-right .filter{
margin: 0 3px;
}
.head-right .jump-wrong {
margin-right: 40px;
}
.head-right .jump-wrong, .head-right .filter{
padding: 0 10px;
background: #1F3057;
cursor: context-menu;
}
.head-right .jump-wrong:hover, .head-right .filter:hover{
background: #283D6F
}
.head-right .filter.active{
background: #8B632A;
}
.steps-content {
background: rgb(18,28,52);
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: -moz-box;
display: -moz-flex;
display: flex;
-webkit-box-align: stretch;
-webkit-align-items: stretch;
-moz-box-align: stretch;
-moz-align-items: stretch;
-ms-flex-align: stretch;
align-items: stretch;
}
.step-left{
min-width: 320px;
padding: 30px 20px;
width: 32%;
max-width: 500px;
}
.step-right{
border-left: dashed 1px rgb(102,102,102);
padding: 30px 0px 0 60px;
margin-left: 30px;
vertical-align: top;
min-height: 500px;
width: 100%;
max-width: calc(100% - 410px);
max-width: calc(100% - 600px);
}
.step-left .step {
line-height: 36px;
position: relative;
cursor: context-menu;
padding: 0 10px;
}
.step-left .step:hover {
background: rgb(22,34,62)
}
.step-left .step.active{
background: #040F26
}
.step-left .step>img{
vertical-align: middle;
}
.step-left .step .step-context {
position: absolute;
width: 20px;
top: 10px;
right: -25px;
cursor: context-menu;
opacity: 0.6;
}
.step-left .step .step-context:hover{
opacity: 1;
}
.step-left .order{
margin: 0 5px;
}
.step-left .step_title {
word-break: break-all;
}
.step-left .step-time{
position: absolute;
right: 10px;
}
.step-right .step-head{
font-size: 24px;
font-weight: bold;
margin-bottom: 15px;
word-break: break-all;
}
.step-right .step-status{
margin-right: 20px;
border-radius: 5px;
font-size: 18px;
font-weight: bolder;
padding: 3px 7px;
}
.step-right .step-status.success{
background: #417505;
}
.step-right .step-status.fail{
background: #fd5a3e
}
.step-right .step-infos{
line-height: 30px;
}
.step-right .step-infos .content-val.success {
color: #97cc64;
}
.step-right .step-infos .content-val.fail {
color: #fd5a3e;
}
.step-right .step-infos img{
vertical-align: middle;
margin: 0 5px;
}
.step-right .bold{
font-size: 18px;
font-weight: bold;
}
.step-right .step-args {
width: 100%;
border-top: solid 1px #212f53;
margin-top: 20px;
padding-top: 30px;
padding-bottom: 50px;
}
.step-right .step-args .crop_image {
margin-top: 7px;
max-width: calc(100% - 80px);
max-height: 100%;
}
.step-right .step-args .desc{
margin-left: 50px;
}
.step-right .fancybox{
margin: auto;
position: relative;
max-width: 100%;
}
.step-right .step-args .fluid {
display: inline-block;
vertical-align: top;
margin-bottom: 20px;
}
.fluid.infos{
min-width: 300px;
}
.step-right .fluid.screens, .step-right .fluid.traces{
width: 100%;
max-width: calc(100% - 330px);
min-width: 500px;
}
.fancybox .screen{
max-width: 100%;
border: solid 1px #212f53;
max-height: 600px;
}
.fancybox .target{
position: absolute;
width: 50px;
height: 50px;
animation-name: rubberBand;
-webkit-animation-name: rubberBand; /* Safari 和 Chrome */
-webkit-animation-iteration-count: infinite;
animation-iteration-count: infinite;
-webkit-animation-duration: 1s;
animation-duration: 1s;
-webkit-animation-fill-mode: both;
animation-fill-mode: both;
}
.fancybox .rect {
position: absolute;
border: solid 2px red;
border-radius: 3px;
background: transparent;
}
.fancybox .arrow {
display: flex;
align-items: center;
left: 100px;
top: 100px;
position: absolute;
width: 120px;
margin-top: -15px;
margin-left: -6px;
}
.fancybox .arrow .start {
width: 12px;
height: 12px;
border-radius: 6px;
background-color: red;
}
.fancybox .arrow .line {
flex: 1;
background: red;
height: 10px;
}
.fancybox .arrow .end {
width: 0;
height: 0;
border-top: 15px solid transparent;
border-bottom: 15px solid transparent;
border-left: 20px solid red;
}
pre.trace {
white-space: pre-wrap;
word-break: break-word;
}
#pageTool {
margin-top: 50px;
position: relative;
height: 50px;
}
#pageTool .js-page-first, #pageTool .js-page-last{
display: none;
}
#pageTool ul{
padding-left: 0;
}
#pageTool .ui-paging-container li{
margin-bottom: 10px;
}
#pageTool .ui-pager-disabled{
color: rgb(59, 81, 134);
border: solid 1px #233868;
background: transparent;
}
#pageTool .focus, #pageTool li.ui-pager:hover {
color:rgb(74,144,226);
background: transparent;
border: solid 1px rgb(74,144,226);
}
#pageTool .steps-total {
display: block;
margin: auto;
text-align: center;
color: rgb(74,144,226);
font-size: 12px;
position: absolute;
top: 4px;
right: -14px;
}
#pageTool .ui-paging-container{
position: absolute;
right: 50px;
top: 0px;
}
#pageTool .ui-select-pagesize, #pageTool .ui-paging-count{
background: transparent;
color: rgb(74,144,226);
}
.row.gif-wrap {
position: fixed;
bottom: 0;
right: 0;
}
.row.gif-wrap .menu{
display: block;
text-align: right;
background: rgba(0, 0, 0, 0.7);
min-width: 100px;
height: 38px;
}
.row.gif-wrap .pattern1, .row.gif-wrap .col-md-6{
display: none;
}
.row.gif-wrap.show .pattern1, .row.gif-wrap.show .col-md-6{
display: block;
}
.row.gif-wrap .pattern2{
display: block;
}
.row.gif-wrap.show .pattern2{
display: none;
}
.row.gif-wrap .pattern {
margin-right: 14px;
}
.row.gif-wrap .pattern>div{
display: inline-block;
padding: 8px;
width: 20px;
height: 20px;
margin-left: 2px;
}
.row.gif-wrap .pattern .minimize {
width: 18px;
}
.row.gif-wrap .embed-responsive{
display: inline-block;
position: relative;
}
.row.gif-wrap .embed-responsive .open_in_new_tab{
position: absolute;
top: -34px;
right: 100px;
transition: all 0.3s ease-out;
background: rgba(0, 0, 0, 0.7);
padding: 8px;
border-radius: 44px;
width: 16px;
height: 15px;
z-index: 2;
}
.row.gif-wrap img{
max-width: 100%;
max-height: 100%;
opacity: 0.6;
}
.row.gif-wrap img:hover{
opacity: 1;
transform: scale(1.1);
}
.row.gif-wrap .embed-responsive-item {
max-width: 500px;
max-height: 500px;
}
.mask {
position: fixed;
left: 0;
top: 0;
width: 100%;
height: 100%;
background: rgba(255, 255, 255, 0.2);
z-index: 2;
display: none;
}
.mask .content {
width: 80%;
height: calc(100% - 140px);
margin: auto;
margin-top: 60px;
padding-top: 40px;
position: relative;
}
.mask .content .console-content{
height: 100%;
overflow-y: auto;
}
#magnify.mask{
background: rgba(255, 255, 255, 0.7);
}
#magnify .content{
padding: 0;
height: calc(100% - 100px);
display:flex;
justify-content: center;
align-items: center;
}
#magnify .fancybox, #magnify .crop_image{
display:block;
max-width:100%;
max-height:100%;
position: relative;
}
#magnify .fancybox .screen{
height: auto;
max-height: 100%;
margin: auto;
display: block;
}
#close-console {
position: absolute;
top: 7px;
right: 10px;
width: 25px;
border: solid 1px white;
border-radius: 30px;
}
#close-console:hover {
background: rgba(255, 255, 255, 0.3);
}
.footer {
height: 120px;
color: #999;
min-width: 1160px;
border-top: solid 1px #172036;
position: absolute;
width: 100%;
bottom: -219px;
left: 0;
}
.footer-content {
display: flex;
align-items: center;
justify-content: center;
padding: 34px 0;
}
.foo {
min-width: 300px;
width: 20%;
}
.foo:last-child {
min-width: 455px;
font-size: 14px;
}
.footer a{
text-decoration: none;
display: block;
color: inherit;
}
.footer .foo >div {
display: inline-block;
vertical-align: middle;
}
.footer .interfaces .icon:first-child{
border: none;
}
.footer .interfaces .icon{
margin: 15px 0;
display: inline-block;
padding: 0 16px;
border-left: solid 1px #666666;
}
.footer .icon img{
vertical-align: middle;
}
.footer .apps .icon {
display: inline-block;
line-height: 40px;
margin-right: 30px;
}
.footer .corp img{
width: 105px;
vertical-align: middle;
margin-right: 20px;
}
/* animation */
@-webkit-keyframes rubberBand {
from {
-webkit-transform: scale3d(1, 1, 1);
transform: scale3d(1, 1, 1);
}
30% {
-webkit-transform: scale3d(1.25, 0.75, 1);
transform: scale3d(1.25, 0.75, 1);
}
40% {
-webkit-transform: scale3d(0.75, 1.25, 1);
transform: scale3d(0.75, 1.25, 1);
}
50% {
-webkit-transform: scale3d(1.15, 0.85, 1);
transform: scale3d(1.15, 0.85, 1);
}
65% {
-webkit-transform: scale3d(.95, 1.05, 1);
transform: scale3d(.95, 1.05, 1);
}
75% {
-webkit-transform: scale3d(1.05, .95, 1);
transform: scale3d(1.05, .95, 1);
}
to {
-webkit-transform: scale3d(1, 1, 1);
transform: scale3d(1, 1, 1);
}
}
@keyframes down {
0% { bottom: 10px; }
50% {bottom: 3px;}
100% { bottom: 10px; }
}
@-moz-keyframes down /* Firefox */{
0% { bottom: 10px; }
50% {bottom: 3px;}
100% { bottom: 10px; }
}
@-webkit-keyframes down /* Safari 和 Chrome */{
0% { bottom: 10px; }
50% {bottom: 3px;}
100% { bottom: 10px; }
}
@-o-keyframes down /* Opera */{
0% { bottom: 10px; }
50% {bottom: 3px;}
100% { bottom: 10px; }
}
/* 滚动条 */
::-webkit-scrollbar {
width: 6px; /*滚动条的宽度*/
height: 6px; /*滚动条的高度*/
}
::-webkit-scrollbar-thumb:horizontal { /*水平滚动条的样式*/
background-color: #324163;
-webkit-border-radius: 6px;
outline: 2px solid #fff;
}
::-webkit-scrollbar-track-piece {
background-color: rgb(10, 10, 28); /*滚动条的背景颜色*/
-webkit-border-radius: 0; /*滚动条的圆角宽度*/
}
::-webkit-scrollbar-thumb:vertical { /*垂直滚动条的样式*/
height: 50px;
background-color: #324163;
-webkit-border-radius: 4px;
outline: 2px solid #fff;
outline-offset: -2px;
border: 1px solid #324163;
}
::-webkit-scrollbar-thumb:hover { /*滚动条的hover样式*/
height: 50px;
background-color: #9f9f9f;
-webkit-border-radius: 4px;
}
/* 分页 */
.ui-paging-container{color:#666;font-size:12px}.ui-paging-container ul{overflow:hidden;text-align:center}.ui-paging-container li,.ui-paging-container ul{list-style:none}.ui-paging-container li{display:inline-block;padding:3px 6px;margin-left:5px;color:#666}.ui-paging-container li.ui-pager{cursor:pointer;border:1px solid #ddd;border-radius:2px}.ui-paging-container li.focus,.ui-paging-container li.ui-pager:hover{background-color:#288df0;color:#FFF}.ui-paging-container li.ui-paging-ellipse{border:none}.ui-paging-container li.ui-paging-toolbar{padding:0}.ui-paging-container li.ui-paging-toolbar select{height:22px;border:1px solid #ddd;color:#666}.ui-paging-container li.ui-paging-toolbar input{vertical-align:top;line-height:20px;height:20px;padding:0;border:1px solid #ddd;text-align:center;width:30px;margin:0 0 0 5px}.ui-paging-container li.ui-paging-toolbar a{text-decoration:none;display:inline-block;height:20px;border:1px solid #ddd;vertical-align:top;border-radius:2px;line-height:20px;padding:0 3px;cursor:pointer;margin-left:5px;color:#666}.ui-paging-container li.ui-pager-disabled,.ui-paging-container li.ui-pager-disabled:hover{background-color:#f6f6f6;cursor:default;border:none;color:#ddd}
\ No newline at end of file
This diff is collapsed.
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment