新增工具‘HTTPCookie管理器’,支持设置HTTPCookie数据

This commit is contained in:
azhengzz 2021-04-03 23:57:34 +08:00
parent 793d8c7bc3
commit a73e9bca96
17 changed files with 665 additions and 8 deletions

View File

@ -69,19 +69,19 @@ class HTTPCookiePoolManager:
if old_rcj is None:
__class__.ScheduleCookiePool[project_id] = rcj
else:
cls._update_request_cookie_jar(old_rcj=old_rcj, new_rcj=rcj)
cls.update_request_cookie_jar(old_rcj=old_rcj, new_rcj=rcj)
else:
session_id = session_id_manager.get_session_id()
old_rcj = __class__.CookiePool[session_id][type]
if old_rcj is None:
__class__.CookiePool[session_id][type] = rcj
else:
cls._update_request_cookie_jar(old_rcj=old_rcj, new_rcj=rcj)
cls.update_request_cookie_jar(old_rcj=old_rcj, new_rcj=rcj)
else:
raise ValueError('不支持传入type值为%s只支持type=single_case 或 type=build_case' % type)
@classmethod
def _update_request_cookie_jar(cls, old_rcj: RequestsCookieJar, new_rcj: RequestsCookieJar):
def update_request_cookie_jar(cls, old_rcj: RequestsCookieJar, new_rcj: RequestsCookieJar):
"""将新的rcj更新到老的rcj上"""
old_rcj.update(other=new_rcj)
@ -107,7 +107,7 @@ class HTTPCookiePoolManager:
})
@classmethod
def get_request_cookie_jar(cls, type: str) -> Optional[RequestsCookieJar]:
def get_request_cookie_jar(cls, type: str) -> RequestsCookieJar:
"""
获取当前会话中指定类型的cookie数据
:param type: cookie类型 DISPATCHER_TYPE.BUILD或DISPATCHER_TYPE.DEBUG
@ -117,12 +117,12 @@ class HTTPCookiePoolManager:
project_id = session.get('project_id')
if project_id:
if project_id not in __class__.ScheduleCookiePool:
return
cls._add_empty_to_cookie_pool()
return __class__.ScheduleCookiePool[project_id]
else:
session_id = session_id_manager.get_session_id()
if session_id not in __class__.CookiePool:
return
cls._add_empty_to_cookie_pool()
return __class__.CookiePool[session_id][type]
@classmethod

View File

@ -102,6 +102,7 @@ class TOOL_TYPE:
VARIABLE_DEFINITION = 'VARIABLE_DEFINITION'
SCRIPT = 'SCRIPT'
HTTP_REQUEST_HEADER_MANAGER = 'HTTP_REQUEST_HEADER_MANAGER'
HTTP_COOKIE_MANAGER = 'HTTP_COOKIE_MANAGER'
class CONTENT_TYPE:

View File

@ -868,7 +868,8 @@ class SceneDispatcher(AbstractSceneDispatcher):
if tool.status in [STATUS.NORMAL] and tool.tool_type in [TOOL_TYPE.TIMER,
TOOL_TYPE.SCRIPT,
TOOL_TYPE.VARIABLE_DEFINITION,
TOOL_TYPE.HTTP_REQUEST_HEADER_MANAGER]:
TOOL_TYPE.HTTP_REQUEST_HEADER_MANAGER,
TOOL_TYPE.HTTP_COOKIE_MANAGER]:
# ReportToolData表数据字段
report_id = self.dispatcher.report.id
try:
@ -890,6 +891,11 @@ class SceneDispatcher(AbstractSceneDispatcher):
HTTPRequestHeaderManagerToolDispatcher(tool=tool, dispatcher_type=DISPATCHER_TYPE.BUILD,
logger=self.dispatcher_logger,
dispatcher=self.dispatcher).run()
elif tool.tool_type == TOOL_TYPE.HTTP_COOKIE_MANAGER:
from app.cores.tool.dispatcher import HTTPCookieManagerToolDispatcher
HTTPCookieManagerToolDispatcher(tool=tool, dispatcher_type=DISPATCHER_TYPE.BUILD,
logger=self.dispatcher_logger,
dispatcher=self.dispatcher).run()
finally:
# 工具增加调度子数据
dispatcher_detail_id = DispatcherDetail.add(element_type=ELEMENT_TYPE.TOOL, element_id=tool.id,

View File

@ -6,6 +6,7 @@ from app.cores.tool.script import Script
from app.cores.tool.timer import Timer
from app.cores.tool.variable_definition import VariableDefinition
from app.cores.tool.http_request_header_manager import HTTPRequestHeaderManager
from app.cores.tool.http_cookie_manager import HTTPCookieManager
class ScriptToolDispatcher(AbstractToolDispatcher):
@ -127,3 +128,31 @@ class HTTPRequestHeaderManagerToolDispatcher(AbstractToolDispatcher):
def run(self):
super().run()
class HTTPCookieManagerToolDispatcher(AbstractToolDispatcher):
def __init__(self, tool, dispatcher_type=DISPATCHER_TYPE.BUILD, logger=None, dispatcher=None):
"""
:param tool: 单个HTTPCookieManager Tool工具组件
:type tool: Tool
:param dispatcher_type: 标识构建是通过单独组件调试(DISPATCHER_TYPE.DEBUG)还是通过模块/项目构建测试(DISPATCHER_TYPE.BUILD)
:type dispatcher_type: str
:param logger: 当dispatcher_type为DISPATCHER_TYPE.BUILD时需要传入调度日志
:type logger: DispatcherLogger
:param dispatcher: 当dispatcher_type为DISPATCHER_TYPE.BUILD时需要传入调度数据
:type dispatcher: Dispatcher
"""
super().__init__(tool=tool, dispatcher_type=dispatcher_type, logger=logger, dispatcher=dispatcher)
def set_up(self):
super().set_up()
def execute(self):
super().execute()
HTTPCookieManager(tool=self.tool, dispatcher_logger=self.dispatcher_logger).exec_tool()
def tear_down(self):
super().tear_down()
def run(self):
super().run()

View File

@ -0,0 +1,31 @@
# coding=utf-8
from requests.cookies import RequestsCookieJar
from app.cores.case.http.http_cookie_pool_manager import HTTPCookiePoolManager
from app.cores.dictionaries import DISPATCHER_TYPE
class HTTPCookieManager:
def __init__(self, tool, dispatcher_logger):
"""
初始化HTTPCookieManager工具对象
:param tool: 工具
:type tool: Tool
:param dispatcher_logger: 日志
:type dispatcher_logger: DispatcherLogger
"""
self.http_cookie_manager_tool = tool.specific_tool
self.dispatcher_logger = dispatcher_logger
def exec_tool(self):
self.dispatcher_logger.logger.info('[HTTPCookie管理器][执行]')
rcj = HTTPCookiePoolManager.get_request_cookie_jar(type=DISPATCHER_TYPE.BUILD)
new_rcj = RequestsCookieJar()
for row in self.http_cookie_manager_tool.http_cookie_manager_list:
new_rcj.set(name=row.name_,
value=row.value_,
domain=row.domain_,
path=row.path_,
secure=row.secure)
HTTPCookiePoolManager.update_request_cookie_jar(old_rcj=rcj, new_rcj=new_rcj)

View File

@ -1004,6 +1004,8 @@ class Tool(db.Model):
return VariableDefinitionTool.query.filter_by(tool_id=self.id).first()
if self.tool_type == TOOL_TYPE.HTTP_REQUEST_HEADER_MANAGER:
return HTTPRequestHeaderManagerTool.query.filter_by(tool_id=self.id).first()
if self.tool_type == TOOL_TYPE.HTTP_COOKIE_MANAGER:
return HTTPCookieManagerTool.query.filter_by(tool_id=self.id).first()
@classmethod
def exist_and_status_not_delete(cls, tool_id) -> bool:
@ -1051,6 +1053,9 @@ class Tool(db.Model):
elif tool_type == TOOL_TYPE.HTTP_REQUEST_HEADER_MANAGER:
specific_tool = HTTPRequestHeaderManagerTool.new_tool()
specific_tool.tool = tool
elif tool_type == TOOL_TYPE.HTTP_COOKIE_MANAGER:
specific_tool = HTTPCookieManagerTool.new_tool()
specific_tool.tool = tool
else:
raise ValueError('不支持当前tool_type类型, tool_type=%s' % tool_type)
db.session.add(specific_tool)
@ -1557,6 +1562,172 @@ class HTTPRequestHeaderManagerList(db.Model):
return _p(self.value)
class HTTPCookieManagerTool(db.Model):
"""
关系说明
tool: HTTPCookieManagerTool对应的工具对象 HTTPCookieManagerTool:Tool is 1:1
http_cookie_manager_list: HTTPCookieManagerTool工具所包含的所有变量与值数据 HTTPCookieManagerTool:HTTPCookieManagerList is 1:N
"""
id = db.Column(db.Integer, primary_key=True)
# relationship
tool_id = db.Column(db.Integer, db.ForeignKey('tool.id'))
tool = db.relationship('Tool')
http_cookie_manager_list = db.relationship('HTTPCookieManagerList',
back_populates='http_cookie_manager_tool',
cascade='all, delete-orphan')
@property
def attributes(self):
return [{
'name': row.name,
'value': row.value,
'domain': row.domain,
'path': row.path,
'secure': row.secure,
} for row in self.http_cookie_manager_list]
@classmethod
def new_tool(cls):
"""新增默认"""
http_cookie_manager_tool = cls()
http_cookie_manager_tool.http_cookie_manager_list = []
http_cookie_manager_tool.http_cookie_manager_list.append(
HTTPCookieManagerList(name='cookie_name',
value='cookie_value',
domain='localhost',
path='/',
secure=False)
)
db.session.add(http_cookie_manager_tool)
db.session.commit()
return http_cookie_manager_tool
@classmethod
def update(cls, name, description, tool_id, attributes):
"""
更新工具数据
:param tool_id: 工具编号
:type tool_id: int
:param name: 名称
:type name: str
:param description: 注释
:type description: str
:param attributes: HTTPCookieManager数据列表
:type attributes: List[Mapping[str, str]]
"""
tool = Tool.query.filter_by(id=tool_id).first()
if tool:
tool.name = name
tool.description = description
http_cookie_manager_tool = tool.specific_tool
http_cookie_manager_tool.http_cookie_manager_list = []
for attr in attributes:
http_cookie_manager_tool.http_cookie_manager_list.append(
HTTPCookieManagerList(name=attr.get('name', ''),
value=attr.get('value', ''),
domain=attr.get('domain', ''),
path=attr.get('path', ''),
secure=attr.get('secure', False))
)
db.session.commit()
@classmethod
def add(cls, name, description, attributes, status=STATUS.NORMAL):
"""
新增一条工具数据
:param name: 名称
:type name: str
:param description: 注释
:type description: str
:param attributes: HTTPCookieManager数据列表
:type attributes: List[Mapping[str, str]]
:param status: 案例状态删除 正常
:type status: str
"""
tool = Tool(
name=name,
description=description,
status=status,
tool_type=TOOL_TYPE.HTTP_COOKIE_MANAGER,
)
http_cookie_manager_tool = cls()
http_cookie_manager_tool.http_cookie_manager_list = []
for attr in attributes:
http_cookie_manager_tool.http_cookie_manager_list.append(
HTTPCookieManagerList(name=attr.get('name', ''),
value=attr.get('value', ''),
domain=attr.get('domain', ''),
path=attr.get('path', ''),
secure=attr.get('secure', False))
)
http_cookie_manager_tool.tool = tool
db.session.add(tool)
db.session.add(http_cookie_manager_tool)
db.session.commit()
return http_cookie_manager_tool
def copy_from_self(self):
"""
复制一个新的工具
:return: 新的工具
:rtype: Tool
"""
# 先获取变量键值对数据
copy_tool = self.add(
# Tool
name='Copy' + self.tool.name,
description=self.tool.description,
status=self.tool.status,
# HTTPCookieManagerTool
attributes=self.attributes,
)
return copy_tool
class HTTPCookieManagerList(db.Model):
"""
字段说明
name: 名称
value:
domain:
path: 路径
secure: 安全
关系说明
http_cookie_manager_tool: HTTPCookieManager数据列表对应的HTTPCookieManager工具对象 HTTPCookieManagerList:HTTPCookieManagerTool is N:1
"""
# 需要转换为json数据格式的字段
render_field_list = ['name', 'value', 'domain', 'path', 'secure']
# filed
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(512), nullable=False, default='', server_default='')
value = db.Column(db.Text, nullable=False, default='', server_default='')
domain = db.Column(db.String(512), nullable=False, default='', server_default='')
path = db.Column(db.String(512), nullable=False, default='', server_default='')
secure = db.Column(db.Boolean, nullable=False, default=False, server_default='0')
# relationship
http_cookie_manager_tool_id = db.Column(db.Integer, db.ForeignKey('http_cookie_manager_tool.id'))
http_cookie_manager_tool = db.relationship('HTTPCookieManagerTool',
back_populates='http_cookie_manager_list')
@property
def name_(self):
return _p(self.name)
@property
def value_(self):
return _p(self.value)
@property
def domain_(self):
return _p(self.domain)
@property
def path_(self):
return _p(self.path)
class Case(db.Model):
"""
字段说明
@ -3225,6 +3396,10 @@ class ReportToolData(db.Model):
back_populates='report_tool_data',
uselist=False,
cascade='all, delete-orphan')
report_http_cookie_manager_tool_data = db.relationship('ReportHTTPCookieManagerToolData',
back_populates='report_tool_data',
uselist=False,
cascade='all, delete-orphan')
@classmethod
def add(cls, tool, report_id, dispatcher_detail_id):
@ -3241,6 +3416,9 @@ class ReportToolData(db.Model):
elif tool.tool_type == TOOL_TYPE.HTTP_REQUEST_HEADER_MANAGER:
ReportHTTPRequestHeaderManagerToolData.add(variables=tool.specific_tool.variables,
report_tool_data_id=report_tool_data.id)
elif tool.tool_type == TOOL_TYPE.HTTP_COOKIE_MANAGER:
ReportHTTPCookieManagerToolData.add(attributes=tool.specific_tool.attributes,
report_tool_data_id=report_tool_data.id)
return report_tool_data
@ -3368,6 +3546,59 @@ class ReportHTTPRequestHeaderManagerToolListData(db.Model):
back_populates='report_http_request_header_manager_tool_list_data')
class ReportHTTPCookieManagerToolData(db.Model):
# field
id = db.Column(db.Integer, primary_key=True)
# relationship
report_tool_data_id = db.Column(db.Integer, db.ForeignKey('report_tool_data.id'))
report_tool_data = db.relationship('ReportToolData', back_populates='report_http_cookie_manager_tool_data')
report_http_cookie_manager_tool_list_data = db.relationship('ReportHTTPCookieManagerToolListData',
back_populates='report_http_cookie_manager_tool_data',
cascade='all, delete-orphan')
@property
def attributes(self):
return [{
'name': row.name,
'value': row.value,
'domain': row.domain,
'path': row.path,
'secure': row.secure,
} for row in self.report_http_cookie_manager_tool_list_data]
@classmethod
def add(cls, attributes, report_tool_data_id):
report_http_cookie_manager_tool_data = ReportHTTPCookieManagerToolData(report_tool_data_id=report_tool_data_id)
db.session.add(report_http_cookie_manager_tool_data)
db.session.commit() # commit后report_http_cookie_manager_tool_data.id才有值否则为None
for attr in attributes:
db.session.add(ReportHTTPCookieManagerToolListData(
name=attr.get('name', ''),
value=attr.get('value', ''),
domain=attr.get('domain', ''),
path=attr.get('path', ''),
secure=attr.get('secure', False),
report_http_cookie_manager_tool_data_id=report_http_cookie_manager_tool_data.id,
))
db.session.commit()
class ReportHTTPCookieManagerToolListData(db.Model):
# field
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(512), nullable=False, default='', server_default='')
value = db.Column(db.Text, nullable=False, default='', server_default='')
domain = db.Column(db.String(512), nullable=False, default='', server_default='')
path = db.Column(db.String(512), nullable=False, default='', server_default='')
secure = db.Column(db.Boolean, nullable=False, default=False, server_default='0')
# relationship
report_http_cookie_manager_tool_data_id = db.Column(db.Integer, db.ForeignKey('report_http_cookie_manager_tool_data.id'))
report_http_cookie_manager_tool_data = db.relationship('ReportHTTPCookieManagerToolData',
back_populates='report_http_cookie_manager_tool_list_data')
class Scheduler(db.Model):
"""
调度定时任务

View File

@ -20,7 +20,8 @@ from app.utils.util import get_form_from_request, exception_handle, get_project_
from app.models import Case, Project, Module, Scene, HTTPCase, SSHCase, SQLCase, Dispatcher, DispatcherDetail, Report, \
SubElementInLogicController, LogicController, IfController, WhileController, LoopController, SimpleController, \
Scheduler, DingTalkRobotSetting, DingTalkRobotSettingAssociationProject, DebugCase, Tool, TimerTool, ScriptTool, \
VariableDefinitionTool, EmailReceiverSetting, EmailReceiverSettingAssociationProject, HTTPRequestHeaderManagerTool
VariableDefinitionTool, EmailReceiverSetting, EmailReceiverSettingAssociationProject, HTTPRequestHeaderManagerTool,\
HTTPCookieManagerTool
from app.template_global import render_to_json
from app.extensions import dispatcher_scheduler
from app.template_global import sort_by_order_in_project, sort_by_order_in_module, sort_by_order_in_logic_controller
@ -799,6 +800,39 @@ def save_http_request_header_manager_tool():
})
@bp.route('/tool/http_cookie_manager/save', methods=['POST'])
@login_required
def save_http_cookie_manager_tool():
# 参数校验
exist, form_tool_id = get_form_from_request(request, 'tool_id')
if not exist: return form_tool_id
exist, form_tool_name = get_form_from_request(request, 'tool_name')
if not exist: return form_tool_name
exist, form_tool_description = get_form_from_request(request, 'tool_description')
if not exist: return form_tool_description
exist, form_attrs = get_form_from_request(request, 'attrs')
if not exist: return form_attrs
try:
attributes = json.loads(form_attrs)
HTTPCookieManagerTool.update(
tool_id=form_tool_id,
name=form_tool_name,
description=form_tool_description,
attributes=attributes,
)
except Exception as e:
exception_handle(current_app, e)
return jsonify({
'error_no': -1,
'error_msg': '错误信息 [' + repr(e) + ']',
})
else:
return jsonify({
'error_no': 0,
'error_msg': '',
})
@bp.route('/tool/script/run', methods=['POST'])
@login_required
def run_script_tool():
@ -2290,6 +2324,7 @@ def get_report_detail_tool():
})
report_tool_data = dispatcher_detail.specific_element_report_data
variables = []
attributes = []
if report_tool_data.tool_type == TOOL_TYPE.TIMER:
html_text = render_template('report/_report_detail_timer_tool.html',
dispatcher_detail=dispatcher_detail,
@ -2308,6 +2343,11 @@ def get_report_detail_tool():
dispatcher_detail=dispatcher_detail,
report_tool_data=report_tool_data)
variables = report_tool_data.report_http_request_header_manager_tool_data.variables
elif report_tool_data.tool_type == TOOL_TYPE.HTTP_COOKIE_MANAGER:
html_text = render_template('report/_report_detail_http_cookie_manager_tool.html',
dispatcher_detail=dispatcher_detail,
report_tool_data=report_tool_data)
attributes = report_tool_data.report_http_cookie_manager_tool_data.attributes
else:
html_text = ''
except Exception as e:
@ -2323,6 +2363,7 @@ def get_report_detail_tool():
'html_text': html_text,
'tool_type': report_tool_data.tool_type,
'variables': variables,
'attributes': attributes,
})
@ -2548,6 +2589,7 @@ def tool():
'error_msg': '错误信息 [未找工具数据tool_id=%s]' % form_tool_id,
})
data_variables = []
data_attributes = []
if tool.tool_type == TOOL_TYPE.TIMER:
html_text = render_template('tool/timer.html', tool=tool)
elif tool.tool_type == TOOL_TYPE.SCRIPT:
@ -2558,6 +2600,9 @@ def tool():
elif tool.tool_type == TOOL_TYPE.HTTP_REQUEST_HEADER_MANAGER:
html_text = render_template('tool/http_request_header_manager.html', tool=tool)
data_variables = json.loads(render_to_json(tool.specific_tool.http_request_header_manager_list))
elif tool.tool_type == TOOL_TYPE.HTTP_COOKIE_MANAGER:
html_text = render_template('tool/http_cookie_manager.html', tool=tool)
data_attributes = json.loads(render_to_json(tool.specific_tool.http_cookie_manager_list))
else:
return jsonify({
'error_no': -1,
@ -2577,6 +2622,7 @@ def tool():
'tool_type': tool.tool_type,
'html_text': html_text,
'data_variables': data_variables,
'data_attributes': data_attributes,
})

View File

@ -199,6 +199,9 @@ body {
.icon-tool-http-request-header-manager{
background-image: url(/static/icon/http-request-header.svg);
}
.icon-tool-http-cookie-manager{
background-image: url(/static/icon/cookie.svg);
}
/*div边框样式*/
.border-left-primary {

View File

@ -0,0 +1,3 @@
<svg class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="currentColor">
<path d="M512 938.666667c-235.52-0.256-426.410667-191.146667-426.666667-426.666667 16.810667 4.736 34.133333 7.168 51.626667 7.210667a175.36 175.36 0 0 0 145.066667-74.965334c29.568-42.666667 35.84-97.322667 16.64-145.578666 12.245333 2.176 24.661333 3.285333 37.12 3.328A182.058667 182.058667 0 0 0 478.506667 234.666667a177.536 177.536 0 0 0 36.266666-149.333334c235.648 0.768 426.026667 192.426667 425.301334 428.074667C939.306667 749.013333 747.648 939.392 512 938.666667z m32.554667-146.432a53.376 53.376 0 1 0 20.778666-102.4 53.333333 53.333333 0 0 0-20.778666 102.4zM295.253333 720a71.125333 71.125333 0 1 0-0.853333-0.256h0.682667l0.170666 0.256z m402.389334-106.965333a71.082667 71.082667 0 1 0-43.605334-63.573334c0.682667 26.666667 16.256 50.645333 40.277334 62.208h-0.512l1.28 0.554667 0.853333 0.341333h-0.256l1.792 0.682667 0.170667-0.213333zM512 440.874667a35.584 35.584 0 1 0 13.824 2.816l-0.768-0.341334-1.152-0.426666a35.157333 35.157333 0 0 0-11.904-2.048z m160-177.749334a53.162667 53.162667 0 1 0 20.736 4.266667h-0.426667a53.12 53.12 0 0 0-20.309333-4.266667zM192 405.333333a35.541333 35.541333 0 1 1 0-71.082666 35.541333 35.541333 0 0 1 0 71.082666zM138.666667 298.666667a53.333333 53.333333 0 1 1 0-106.666667 53.333333 53.333333 0 0 1 0 106.666667z m213.333333-71.125334a53.333333 53.333333 0 1 1 0-106.752 53.333333 53.333333 0 0 1 0 106.794667v-0.042667zM227.584 156.458667a35.541333 35.541333 0 1 1 0-71.082667 35.541333 35.541333 0 0 1 0 71.082667z" />
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -236,6 +236,9 @@ function renderToolReportDetail(node){
}else if(data.tool_type === 'HTTP_REQUEST_HEADER_MANAGER'){
// 渲染HTTPRequestHeaderManagerTool工具组件页面
renderHTTPRequestHeaderManagerToolPage(node.data.dispatcher_detail_id, data.variables);
}else if(data.tool_type === 'HTTP_COOKIE_MANAGER'){
// 渲染HTTPCookieManagerTool工具组件页面
renderHTTPCookieManagerToolPage(node.data.dispatcher_detail_id, data.attributes);
}
resolve(['成功了', 'success']); // 也可以传递其他类型参数
}else{
@ -721,6 +724,92 @@ function renderHTTPRequestHeaderManagerToolPage(dispatcher_detail_id, data_varia
table_http_request_header_manager = $container.handsontable(option_table_http_request_header_manager).handsontable('getInstance');
}
}
// 渲染HTTPCookieManagerTool工具组件页面
function renderHTTPCookieManagerToolPage(dispatcher_detail_id, data_attributes) {
// HTTPCookieManager表格对象
let table_http_cookie_manager = null;
// 渲染HTTPCookieManager表格
renderHTTPCookieManagerTable();
// 渲染HTTPCookieManager表格
function renderHTTPCookieManagerTable() {
const option_table_http_request_header_manager = {
data: data_attributes,
rowHeaders: true,
// colHeaders: true,
licenseKey: 'non-commercial-and-evaluation',
// 表格宽度
// width: '95vw', // 不指定宽度使其自适应容器
// 拉伸方式
stretchH: 'all',
// tab键自动换行切换
autoWrapRow: true,
height: '55vh',
// 最大行数
maxRows: 999,
// 允许手工移动行或列
manualRowResize: true,
manualColumnResize: true,
// 列名
colHeaders: [
'名称',
'值',
'域',
'路径',
'安全',
],
// 为列设置默认值
dataSchema: {
name: '',
value: '',
url_encode: false,
content_type: 'text/plain',
include_equals: true,
},
// 设置列数据类型
columns: [
{
data: 'name',
readOnly: true,
},
{
data: 'value',
readOnly: true,
},
{
data: 'domain',
readOnly: true,
},
{
data: 'path',
readOnly: true,
},
{
data: 'secure',
type: 'checkbox',
readOnly: true,
},
],
// 列宽比例
colWidths: [2, 5, 5, 3, 1],
manualRowMove: true,
manualColumnMove: false,
// 右键菜单
// contextMenu: ['row_above', 'row_below', '---------', 'remove_row', '---------', 'undo', 'redo', '---------', 'alignment', '---------', 'copy', 'cut'],
// 列是否支持过滤
filters: false,
// 下拉菜单
// dropdownMenu: ['make_read_only', '---------', 'alignment'],
// 语言
language: 'zh-CN',
// 是否允许无效数据 默认 true
allowInvalid: false,
};
let $container = $(`#table-http-cookie-manager-${dispatcher_detail_id}`);
table_http_cookie_manager = $container.handsontable(option_table_http_request_header_manager).handsontable('getInstance');
}
}
// 渲染报告图表
function renderEcharts() {
@ -872,6 +961,8 @@ function renderReportTree() {
$(`#table-variable-definition-${dispatcher_detail_id}`).handsontable('getInstance').render();
}else if(element_type === 'TOOL' && node.data.tool_type === 'HTTP_REQUEST_HEADER_MANAGER'){
$(`#table-http-request-header-manager-${dispatcher_detail_id}`).handsontable('getInstance').render();
}else if(element_type === 'TOOL' && node.data.tool_type === 'HTTP_COOKIE_MANAGER'){
$(`#table-http-cookie-manager-${dispatcher_detail_id}`).handsontable('getInstance').render();
}
},
1000,
@ -955,6 +1046,8 @@ function renderReportTree() {
return 'icon-tool-variable-definition';
}else if(tool_type === 'HTTP_REQUEST_HEADER_MANAGER'){
return 'icon-tool-http-request-header-manager';
}else if(tool_type === 'HTTP_COOKIE_MANAGER'){
return 'icon-tool-http-cookie-manager';
}
}else if(element_type === undefined) {
return true;

View File

@ -478,6 +478,8 @@ function renderElementCopyTree() {
return 'icon-tool-variable-definition';
}else if(tool_type === 'HTTP_REQUEST_HEADER_MANAGER'){
return 'icon-tool-http-request-header-manager';
}else if(tool_type === 'HTTP_COOKIE_MANAGER'){
return 'icon-tool-http-cookie-manager';
}
}else if(element_type === undefined) {
return true;
@ -1516,6 +1518,8 @@ function showTool(tool_id, tool_type) {
$(`#table-variable-definition-${tool_id}`).handsontable('getInstance').render();
}else if(tool_type === 'HTTP_REQUEST_HEADER_MANAGER'){
$(`#table-http-request-header-manager-${tool_id}`).handsontable('getInstance').render();
}else if(tool_type === 'HTTP_COOKIE_MANAGER'){
$(`#table-http-cookie-manager-${tool_id}`).handsontable('getInstance').render();
}
},
1000,
@ -1899,6 +1903,10 @@ function addToolElement(tool_id) {
let element = getHTTPRequestHeaderManagerToolElement(data.tool_id);
element.init(data.data_variables);
element_tool_dict[data.tool_id] = element;
}else if(data.tool_type === 'HTTP_COOKIE_MANAGER') {
let element = getHTTPCookieManagerToolElement(data.tool_id);
element.init(data.data_attributes);
element_tool_dict[data.tool_id] = element;
}
resolve(['成功了', 'success']); // 也可以传递其他类型参数
}else{

View File

@ -0,0 +1,159 @@
function getHTTPCookieManagerToolElement(tool_id) {
let element = new Object;
element.dom = new Object;
element.obj = new Object;
// 案例页面元素
element.dom.$input_tool_name = $(`#input-tool-name-${tool_id}`);
element.dom.$input_tool_description = $(`#input-tool-description-${tool_id}`);
element.dom.$btn_tool_save = $(`#btn-tool-save-${tool_id}`);
element.dom.$div_navigation_tool_name = $(`.tool-name[data-tool-id=${tool_id}]`);
// 对象
element.obj.table_http_cookie_manager = null; // 变量定义表格
// 初始化
element.init = function(data_variables) {
// 事件绑定
eventBinding();
// 渲染HTTPCookie管理器表格
renderHTTPCookieManagerTable(data_variables);
};
// 事件绑定
function eventBinding() {
element.dom.$input_tool_name.on('change keyup', handleKeyUpAndChange);
element.dom.$btn_tool_save.on('click', saveTool);
function handleKeyUpAndChange(){
let tool_name = element.dom.$input_tool_name.val();
element.dom.$div_navigation_tool_name.children().text(tool_name);
}
}
// 渲染HTTPCookie管理器表格
function renderHTTPCookieManagerTable(data_attributes) {
const option_table_http_cookie_manager = {
data: data_attributes,
rowHeaders: true,
// colHeaders: true,
licenseKey: 'non-commercial-and-evaluation',
// 表格宽度
// width: '95vw', // 不指定宽度使其自适应容器
// 拉伸方式
stretchH: 'all',
// tab键自动换行切换
autoWrapRow: true,
height: '65vh',
// 最大行数
maxRows: 999,
// 允许手工移动行或列
manualRowResize: true,
manualColumnResize: true,
// 列名
colHeaders: [
'名称',
'值',
'域',
'路径',
'安全',
],
// 为列设置默认值
dataSchema: {
name: '',
value: '',
url_encode: false,
content_type: 'text/plain',
include_equals: true,
},
// 设置列数据类型
columns: [
{
data: 'name'
},
{
data: 'value',
},
{
data: 'domain',
},
{
data: 'path',
},
{
data: 'secure',
type: 'checkbox',
},
],
// 列宽比例
colWidths: [2, 5, 5, 3, 1],
manualRowMove: true,
manualColumnMove: false,
// 右键菜单
contextMenu: ['row_above', 'row_below', '---------', 'remove_row', '---------', 'undo', 'redo', '---------', 'alignment', '---------', 'copy', 'cut'],
// 列是否支持过滤
filters: false,
// 下拉菜单
dropdownMenu: ['make_read_only', '---------', 'alignment'],
// 语言
language: 'zh-CN',
// 是否允许无效数据 默认 true
allowInvalid: false,
};
let $container = $(`#table-http-cookie-manager-${tool_id}`);
element.obj.table_http_cookie_manager = $container.handsontable(option_table_http_cookie_manager).handsontable('getInstance');
}
function saveTool() {
let tool_name = element.dom.$input_tool_name.val();
let tool_description = element.dom.$input_tool_description.val();
$.ajax({
type: 'POST',
url: '/ajax/tool/http_cookie_manager/save',
data: {
tool_id: tool_id,
tool_name: tool_name,
tool_description: tool_description,
attrs: JSON.stringify(element.obj.table_http_cookie_manager.getSourceData()),
},
success: function (data, status, xhr) {
if (data.error_no === 0){
message('HTTPCookie保存成功', 'success');
}else{
message("HTTPCookie保存失败: " + data.error_msg, "error");
}
}
});
}
// 关键词查找
element.mark = function (text) {
// 匹配到则返回true
let pat = new RegExp(text);
let value = '';
let markFlag = false;
// 名称
value = element.dom.$input_tool_name.val();
if (pat.test(value)) return true;
// 注释
value = element.dom.$input_tool_description.val();
if (pat.test(value)) return true;
// 期望表格
markFlag = false;
value = element.obj.table_http_cookie_manager.getSourceData();
$.each(value, function (index, row) {
$.each(row, function (column, data) {
if (pat.test(data)){
markFlag = true;
return false;
}
});
});
if (markFlag) return true;
// 未匹配到返回false
return false;
};
return element;
}

View File

@ -0,0 +1,10 @@
<div class="container-fluid report-detail-data" id="dispatcher-detail-{{ dispatcher_detail.id }}" data-element-type="TOOL" style="display: none;">
<h4>工具名称: {{ dispatcher_detail.element_name }}</h4>
<h6>开始时间: {{ dispatcher_detail.start_time }}</h6>
<h6>调度编号: {{ dispatcher_detail.dispatcher_id }}</h6>
<h6>元素编号: {{ dispatcher_detail.element_id }}</h6>
<h6>HTTPCookie管理器:</h6>
<div class="container-fluid p-0 mt-2">
<div id="table-http-cookie-manager-{{ dispatcher_detail.id }}"></div>
</div>
</div>

View File

@ -100,6 +100,15 @@
</div>
</div>
<div class="tab-pane fade" id="v-pills-tool" role="tabpanel">
<div class="btn btn-outline-primary" data-scene-id="{{ scene.id }}" onclick="addTool({{ scene.scene_controller.logic_controller.id }}, 'HTTP_COOKIE_MANAGER')">
<h5 class="text-left">
HTTPCookieManager
<svg class="icon float-right" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="currentColor">
<path d="M512 938.666667c-235.52-0.256-426.410667-191.146667-426.666667-426.666667 16.810667 4.736 34.133333 7.168 51.626667 7.210667a175.36 175.36 0 0 0 145.066667-74.965334c29.568-42.666667 35.84-97.322667 16.64-145.578666 12.245333 2.176 24.661333 3.285333 37.12 3.328A182.058667 182.058667 0 0 0 478.506667 234.666667a177.536 177.536 0 0 0 36.266666-149.333334c235.648 0.768 426.026667 192.426667 425.301334 428.074667C939.306667 749.013333 747.648 939.392 512 938.666667z m32.554667-146.432a53.376 53.376 0 1 0 20.778666-102.4 53.333333 53.333333 0 0 0-20.778666 102.4zM295.253333 720a71.125333 71.125333 0 1 0-0.853333-0.256h0.682667l0.170666 0.256z m402.389334-106.965333a71.082667 71.082667 0 1 0-43.605334-63.573334c0.682667 26.666667 16.256 50.645333 40.277334 62.208h-0.512l1.28 0.554667 0.853333 0.341333h-0.256l1.792 0.682667 0.170667-0.213333zM512 440.874667a35.584 35.584 0 1 0 13.824 2.816l-0.768-0.341334-1.152-0.426666a35.157333 35.157333 0 0 0-11.904-2.048z m160-177.749334a53.162667 53.162667 0 1 0 20.736 4.266667h-0.426667a53.12 53.12 0 0 0-20.309333-4.266667zM192 405.333333a35.541333 35.541333 0 1 1 0-71.082666 35.541333 35.541333 0 0 1 0 71.082666zM138.666667 298.666667a53.333333 53.333333 0 1 1 0-106.666667 53.333333 53.333333 0 0 1 0 106.666667z m213.333333-71.125334a53.333333 53.333333 0 1 1 0-106.752 53.333333 53.333333 0 0 1 0 106.794667v-0.042667zM227.584 156.458667a35.541333 35.541333 0 1 1 0-71.082667 35.541333 35.541333 0 0 1 0 71.082667z"></path>
</svg>
</h5>
<p class="text-left">定义HTTPCookie.</p>
</div>
<div class="btn btn-outline-primary" data-scene-id="{{ scene.id }}" onclick="addTool({{ scene.scene_controller.logic_controller.id }}, 'HTTP_REQUEST_HEADER_MANAGER')">
<h5 class="text-left">
HTTPRequestHeaderManager

View File

@ -146,6 +146,7 @@ class="bg-gradient-grey"
<script src="{{ url_for('static', filename='js/tool/script.js') }}"></script>
<script src="{{ url_for('static', filename='js/tool/variable_definition.js') }}"></script>
<script src="{{ url_for('static', filename='js/tool/http_request_header_manager.js') }}"></script>
<script src="{{ url_for('static', filename='js/tool/http_cookie_manager.js') }}"></script>
<script>
let project_id = {{ project.id }};
</script>

View File

@ -0,0 +1,26 @@
<div class="row container-fluid element-data element-tool mt-2 ml-0" data-tool-id="{{ tool.id }}" data-tool-type="{{ tool.tool_type }}" style="display: none">
<h4>HTTPCookie管理器</h4>
<div class="input-group input-group-sm">
<div class="input-group-prepend">
<label class="input-group-text" for="input-tool-name-{{ tool.id }}">名称</label>
</div>
<input id="input-tool-name-{{ tool.id }}" type="text" class="form-control" placeholder="这里填写案例名称" value="{{ tool.name }}">
</div>
<div class="input-group input-group-sm mb-1">
<div class="input-group-prepend">
<label class="input-group-text" for="input-tool-description-{{ tool.id }}">注释</label>
</div>
<input id="input-tool-description-{{ tool.id }}" type="text" class="form-control" placeholder="这里填写注释说明" value="{{ tool.description }}">
</div>
<div class="container-fluid d-flex align-items-center justify-content-between pr-0 mr-0 pl-0 ml-0 mt-2">
<label class=" control-label">存储在Cookie管理器中的Cookie:</label>
<div class="btn-toolbar pr-0 mr-2" role="toolbar">
<div class="btn-group" role="group">
<button id="btn-tool-save-{{ tool.id }}" type="button" class="btn btn-primary">保存</button>
</div>
</div>
</div>
<div class="container-fluid p-0 mt-2">
<div id="table-http-cookie-manager-{{ tool.id }}"></div>
</div>
</div>

View File

@ -184,6 +184,7 @@
请求组件 | SQL | 支持MySQL数据库
请求组件 | Debug | 获取执行时上下文中所有定义的变量和值
工具组件 | HTTPRequestHeaderManager | 设置HTTP请求头数据
工具组件 | HTTPCookieManager | 设置HTTPCookie数据
工具组件 | VariableDefinition | 定义变量
工具组件 | Timer | 定时器, 暂停一段时间后继续执行
工具组件 | Script | 支持编写Python脚本, 灵活处理复杂逻辑和数据