Merge branch 'pr_38' into Develop_Branch

# Conflicts:
#	src/main/resources/static/ruoyi/js/common.js
This commit is contained in:
seagull 2022-01-27 09:41:32 +08:00
commit 6d0dff1e5d
20 changed files with 870 additions and 68 deletions

View File

@ -32,7 +32,7 @@
<commons.io.version>2.5</commons.io.version> <commons.io.version>2.5</commons.io.version>
<commons.fileupload.version>1.3.3</commons.fileupload.version> <commons.fileupload.version>1.3.3</commons.fileupload.version>
<bitwalker.version>1.19</bitwalker.version> <bitwalker.version>1.19</bitwalker.version>
<lombok.version>1.16.18</lombok.version> <!-- <lombok.version>1.16.18</lombok.version>-->
<velocity.version>1.7</velocity.version> <velocity.version>1.7</velocity.version>
<kaptcha.version>2.3.2</kaptcha.version> <kaptcha.version>2.3.2</kaptcha.version>
<swagger.version>2.7.0</swagger.version> <swagger.version>2.7.0</swagger.version>
@ -286,7 +286,11 @@
<groupId>io.netty</groupId> <groupId>io.netty</groupId>
<artifactId>netty-all</artifactId> <artifactId>netty-all</artifactId>
</dependency> </dependency>
</dependencies> <dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
<!--排除版本管理警告--> <!--排除版本管理警告-->
<dependencyManagement> <dependencyManagement>
<dependencies> <dependencies>

View File

@ -17,9 +17,12 @@ public class WebDebugCaseEntity implements Serializable {
*/ */
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private Integer caseId; private Integer caseId;
private Integer userId; private Integer userId;
private String loadpath; private String loadpath;
//修改点
private Integer caseType;
private Integer browserType;
public Integer getCaseId() { public Integer getCaseId() {
return caseId; return caseId;
} }
@ -39,4 +42,15 @@ public class WebDebugCaseEntity implements Serializable {
this.loadpath = loadpath; this.loadpath = loadpath;
} }
//修改点
public Integer getCaseType(){return caseType; }
public void setCaseType(Integer caseType) {
this.caseType = caseType;
}
public Integer getBrowserType() {
return browserType;
}
public void setBrowserType(Integer browserType) {
this.browserType = browserType;
}
} }

View File

@ -297,7 +297,7 @@ public class OpenPostApiController
tce.setCaseId(projectCase.getCaseId()); tce.setCaseId(projectCase.getCaseId());
TaskCaseExecute taskCaseExecute = taskCaseExecuteService.selectTaskCaseExecuteByTaskIdAndCaseId(tce); TaskCaseExecute taskCaseExecute = taskCaseExecuteService.selectTaskCaseExecuteByTaskIdAndCaseId(tce);
List<TaskCaseLog> loglist = taskCaseLogService.selectTaskCaseLogListByTaskCaseId(taskCaseExecute.getTaskCaseId()); List<TaskCaseLog> loglist = taskCaseLogService.selectTaskCaseLogListByTaskCaseId(taskCaseExecute.getTaskCaseId(),null);
for(TaskCaseLog tcl:loglist){ for(TaskCaseLog tcl:loglist){
if(tcl.getLogDetail().contains("测试结果:")){ if(tcl.getLogDetail().contains("测试结果:")){
result = tcl.getLogDetail(); result = tcl.getLogDetail();

View File

@ -54,13 +54,15 @@ public class TaskCaseLogController extends BaseController
response.setCharacterEncoding("utf-8"); response.setCharacterEncoding("utf-8");
PrintWriter pw = response.getWriter(); PrintWriter pw = response.getWriter();
String taskCaseIdStr = request.getParameter("taskCaseId"); String taskCaseIdStr = request.getParameter("taskCaseId");
String errorInfo = request.getParameter("errorInfo");
int taskCaseId = 0; int taskCaseId = 0;
// 得到客户端传递的查询参数 // 得到客户端传递的查询参数
if (StringUtils.isNotEmpty(taskCaseIdStr)) { if (StringUtils.isNotEmpty(taskCaseIdStr)) {
taskCaseId = Integer.parseInt(taskCaseIdStr); taskCaseId = Integer.parseInt(taskCaseIdStr);
} }
List<TaskCaseLog> loglist = taskCaseLogService.selectTaskCaseLogListByTaskCaseId(taskCaseId); List<TaskCaseLog> loglist = taskCaseLogService.selectTaskCaseLogListByTaskCaseId(taskCaseId,errorInfo);
// 转换成json字符串 // 转换成json字符串
JSONArray recordJson= JSONArray.parseArray(JSON.toJSONString(loglist)); JSONArray recordJson= JSONArray.parseArray(JSON.toJSONString(loglist));
pw.print(recordJson); pw.print(recordJson);

View File

@ -35,7 +35,7 @@ public interface ITaskCaseLogService
* @author Seagull * @author Seagull
* @date 2019年4月11日 * @date 2019年4月11日
*/ */
List<TaskCaseLog> selectTaskCaseLogListByTaskCaseId(Integer taskCaseId); List<TaskCaseLog> selectTaskCaseLogListByTaskCaseId(Integer taskCaseId,String errorInfo);
/** /**
* 新增用例日志明细 * 新增用例日志明细

View File

@ -2,6 +2,7 @@ package com.luckyframe.project.testexecution.taskCaseLog.service;
import java.util.List; import java.util.List;
import com.luckyframe.common.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@ -53,10 +54,13 @@ public class TaskCaseLogServiceImpl implements ITaskCaseLogService
* @date 2019年4月11日 * @date 2019年4月11日
*/ */
@Override @Override
public List<TaskCaseLog> selectTaskCaseLogListByTaskCaseId(Integer taskCaseId) public List<TaskCaseLog> selectTaskCaseLogListByTaskCaseId(Integer taskCaseId,String errorInfo)
{ {
TaskCaseLog taskCaseLog = new TaskCaseLog(); TaskCaseLog taskCaseLog = new TaskCaseLog();
taskCaseLog.setTaskCaseId(taskCaseId); taskCaseLog.setTaskCaseId(taskCaseId);
if(StringUtils.isNotEmpty(errorInfo)) {
taskCaseLog.setLogGrade(errorInfo);
}
return taskCaseLogMapper.selectTaskCaseLogList(taskCaseLog); return taskCaseLogMapper.selectTaskCaseLogList(taskCaseLog);
} }

View File

@ -2,6 +2,7 @@ package com.luckyframe.project.testmanagmt.projectCase.controller;
import java.util.List; import java.util.List;
import cn.hutool.json.JSONUtil;
import org.apache.shiro.authz.annotation.RequiresPermissions; import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
@ -62,6 +63,8 @@ public class ProjectCaseDebugController extends BaseController
ProjectCaseDebug projectCaseDebug=new ProjectCaseDebug(); ProjectCaseDebug projectCaseDebug=new ProjectCaseDebug();
projectCaseDebug.setCaseId(caseId); projectCaseDebug.setCaseId(caseId);
projectCaseDebug.setUserId(ShiroUtils.getUserId().intValue()); projectCaseDebug.setUserId(ShiroUtils.getUserId().intValue());
//修改点
projectCaseDebug.setCaseType(projectCase.getCaseType());
List<Client> clients=clientService.selectClientsByProjectId(projectCase.getProjectId()); List<Client> clients=clientService.selectClientsByProjectId(projectCase.getProjectId());
if(clients.size()>0){ if(clients.size()>0){
List<String> driverPathList=clientService.selectClientDriverListById(clients.get(0).getClientId()); List<String> driverPathList=clientService.selectClientDriverListById(clients.get(0).getClientId());
@ -95,6 +98,9 @@ public class ProjectCaseDebugController extends BaseController
} }
webDebugCaseEntity.setCaseId(projectCaseDebug.getCaseId()); webDebugCaseEntity.setCaseId(projectCaseDebug.getCaseId());
webDebugCaseEntity.setUserId(ShiroUtils.getUserId().intValue()); webDebugCaseEntity.setUserId(ShiroUtils.getUserId().intValue());
//修改点
webDebugCaseEntity.setCaseType(projectCaseDebug.getCaseType());
webDebugCaseEntity.setBrowserType(projectCaseDebug.getBrowserType());
Client client = clientService.selectClientById(projectCaseDebug.getClientId()); Client client = clientService.selectClientById(projectCaseDebug.getClientId());
String url= "http://"+client.getClientIp()+":"+ClientConstants.CLIENT_MONITOR_PORT+"/webDebugCase"; String url= "http://"+client.getClientIp()+":"+ClientConstants.CLIENT_MONITOR_PORT+"/webDebugCase";
String result=HttpRequest.httpClientPost(url, client,JSONObject.toJSONString(webDebugCaseEntity),3000); String result=HttpRequest.httpClientPost(url, client,JSONObject.toJSONString(webDebugCaseEntity),3000);

View File

@ -7,17 +7,13 @@ import java.util.List;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import com.luckyframe.common.utils.poi.ExcelUtil;
import com.luckyframe.project.testmanagmt.projectCaseModule.domain.ProjectCaseModule;
import org.apache.shiro.authz.annotation.RequiresPermissions; import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap; import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONArray;
@ -162,4 +158,36 @@ public class ProjectCaseStepsController extends BaseController
return toAjax(projectCaseStepsService.updateProjectCaseSteps(projectCaseSteps)); return toAjax(projectCaseStepsService.updateProjectCaseSteps(projectCaseSteps));
} }
/**
* @author lifengyang
* 用例步骤导出
*/
@RequiresPermissions("testmanagmt:projectCase:exportcasestep")
@PostMapping("/export")
@ResponseBody
public AjaxResult export(@RequestParam("caseId") Integer caseId)
{
ProjectCase projectCase=projectCaseService.selectProjectCaseById(caseId);
ProjectCaseSteps projectCaseSteps = new ProjectCaseSteps();
projectCaseSteps.setCaseId(caseId);
List<ProjectCaseSteps> stepsList=projectCaseStepsService.selectProjectCaseStepsList(projectCaseSteps);
if(stepsList.size()==0){
projectCaseSteps.setAction("");
projectCaseSteps.setExpectedResult("");
projectCaseSteps.setExtend("");
projectCaseSteps.setProjectId(projectCase.getProjectId());
projectCaseSteps.setStepId(0);
projectCaseSteps.setStepOperation("");
projectCaseSteps.setStepParameters("");
projectCaseSteps.setStepPath("");
projectCaseSteps.setStepSerialNumber(1);
projectCaseSteps.setStepType(projectCase.getCaseType());
stepsList.add(projectCaseSteps);
}
ExcelUtil<ProjectCaseSteps> util = new ExcelUtil<>(ProjectCaseSteps.class);
return util.exportExcel(stepsList, "测试用例步骤");
}
} }

View File

@ -0,0 +1,123 @@
package com.luckyframe.project.testmanagmt.projectCase.controller;
import com.luckyframe.common.utils.poi.ExcelUtil;
import com.luckyframe.project.testmanagmt.projectCase.domain.ProjectCaseSteps;
import com.luckyframe.project.testmanagmt.projectCase.service.IProjectCaseService;
import com.luckyframe.project.testmanagmt.projectCase.service.IProjectCaseStepsService;
import com.luckyframe.project.testmanagmt.projectCaseModule.domain.ProjectCaseModule;
import com.luckyframe.rc.ReadTxt;
import com.luckyframe.rc.Readfile;
import com.luckyframe.rc.entity.ElementAction;
import com.luckyframe.rc.entity.RcWebCaseSteps;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
/**
* @Author lifengyang
* @Date 2021-11-05
* @Version 2.0
*/
@Slf4j
@RestController
@RequestMapping("/testmanagmt/RecordController")
public class RecordController {
@Autowired
private IProjectCaseStepsService projectCaseStepsService;
/**
* 脚本录入插入数据
* StepType默认类型 0 HTTP接口 1 Web UI 2 API驱动 3移动端
*/
@PostMapping(value = "/insert",consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public ResponseEntity insertRecord(@RequestParam("file") MultipartFile file,@RequestParam("projectId") int ProjectId,@RequestParam("caseId") int CaseId,@RequestParam("stepType") int StepType) throws Exception {
log.info("StepType:"+StepType);
if (file.getOriginalFilename().toLowerCase().endsWith(".xlsx")){
ExcelUtil<ProjectCaseSteps> util = new ExcelUtil<>(ProjectCaseSteps.class);
List<ProjectCaseSteps> caseStepsList = util.importExcel(file.getInputStream());
int stepSerialNumber=1;
log.info("开始插入步骤");
for(ProjectCaseSteps projectCaseSteps:caseStepsList){
projectCaseSteps.setProjectId(ProjectId);
projectCaseSteps.setCaseId(CaseId);
projectCaseSteps.setStepSerialNumber(stepSerialNumber);
projectCaseSteps.setCreateTime(new Date());
log.info(""+stepSerialNumber+"步骤为:\n"+projectCaseSteps);
projectCaseStepsService.insertProjectCaseSteps(projectCaseSteps);
stepSerialNumber++;
}
}else {
if (StepType==3){
//解析app自动化测试录制的脚本
ReadTxt readTxt = new ReadTxt();
List<ElementAction> stepList = readTxt.Extract(file);
for (ElementAction elementAction : stepList) {
log.info("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"+ elementAction);
}
List<ProjectCaseSteps> listSteps = new ArrayList<>();
for (ElementAction elementAction : stepList) {
ProjectCaseSteps projectCaseSteps = new ProjectCaseSteps();
projectCaseSteps.setCaseId(CaseId);
projectCaseSteps.setProjectId(ProjectId);
projectCaseSteps.setStepPath(elementAction.getAccess());
projectCaseSteps.setStepParameters(elementAction.getActionValue());
projectCaseSteps.setStepOperation(elementAction.getAction());
projectCaseSteps.setStepType(StepType);
projectCaseSteps.setCreateBy("admin");
projectCaseSteps.setCreateTime(new Date());
listSteps.add(projectCaseSteps);
}
int stepSerialNumber=1;
for(ProjectCaseSteps projectCaseSteps:listSteps){
projectCaseSteps.setStepSerialNumber(stepSerialNumber);
log.info("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~2"+projectCaseSteps);
projectCaseStepsService.insertProjectCaseSteps(projectCaseSteps);
stepSerialNumber++;
}
}else if(StepType==1){
//解析web自动化测试录制的脚本
Readfile Readfile = new Readfile();
LinkedList<RcWebCaseSteps> stepList = Readfile.saveAction(file);
for (RcWebCaseSteps rcWebCaseSteps : stepList) {
log.info("设置包|定位路径:"+ rcWebCaseSteps.getStepPath());
}
List<ProjectCaseSteps> listSteps = new ArrayList<>();
for (RcWebCaseSteps rcWebCaseSteps : stepList) {
ProjectCaseSteps projectCaseSteps = new ProjectCaseSteps();
projectCaseSteps.setCaseId(CaseId);
projectCaseSteps.setProjectId(ProjectId);
projectCaseSteps.setStepPath(rcWebCaseSteps.getStepPath());
projectCaseSteps.setStepParameters(rcWebCaseSteps.getStepParameters());
projectCaseSteps.setStepOperation(rcWebCaseSteps.getStepOperation());
projectCaseSteps.setStepType(StepType);
projectCaseSteps.setCreateBy("admin");
projectCaseSteps.setCreateTime(new Date());
listSteps.add(projectCaseSteps);
}
int stepSerialNumber=1;
log.info("开始插入步骤");
for(ProjectCaseSteps projectCaseSteps:listSteps){
projectCaseSteps.setStepSerialNumber(stepSerialNumber);
log.info(""+stepSerialNumber+"步骤为:\n"+projectCaseSteps);
projectCaseStepsService.insertProjectCaseSteps(projectCaseSteps);
stepSerialNumber++;
}
}
}
return ResponseEntity.ok().build();
}
}

View File

@ -1,5 +1,6 @@
package com.luckyframe.project.testmanagmt.projectCase.domain; package com.luckyframe.project.testmanagmt.projectCase.domain;
import com.luckyframe.framework.aspectj.lang.annotation.Excel;
import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle; import org.apache.commons.lang3.builder.ToStringStyle;
import com.luckyframe.framework.web.domain.BaseEntity; import com.luckyframe.framework.web.domain.BaseEntity;
@ -30,6 +31,28 @@ public class ProjectCaseDebug extends BaseEntity
private Integer clientId; private Integer clientId;
/** 客户端驱动路径 */ /** 客户端驱动路径 */
private String driverPath; private String driverPath;
//修改点
/** 默认类型 0 HTTP接口 1 Web UI 2 API驱动 3移动端 */
private Integer caseType;
/** web UI自动化浏览器类型 0 IE 1 火狐 2 谷歌 3 Edge */
private Integer browserType;
public void setCaseType(Integer caseType) {
this.caseType = caseType;
}
public Integer getCaseType() {
return caseType;
}
public Integer getBrowserType() {
return browserType;
}
public void setBrowserType(Integer browserType) {
this.browserType = browserType;
}
public Integer getClientId() { public Integer getClientId() {
return clientId; return clientId;
@ -47,69 +70,70 @@ public class ProjectCaseDebug extends BaseEntity
this.driverPath = driverPath; this.driverPath = driverPath;
} }
public void setDebugId(Integer debugId) public void setDebugId(Integer debugId)
{ {
this.debugId = debugId; this.debugId = debugId;
} }
public Integer getDebugId() public Integer getDebugId()
{ {
return debugId; return debugId;
} }
public void setCaseId(Integer caseId) public void setCaseId(Integer caseId)
{ {
this.caseId = caseId; this.caseId = caseId;
} }
public Integer getCaseId() public Integer getCaseId()
{ {
return caseId; return caseId;
} }
public void setUserId(Integer userId) public void setUserId(Integer userId)
{ {
this.userId = userId; this.userId = userId;
} }
public Integer getUserId() public Integer getUserId()
{ {
return userId; return userId;
} }
public void setDebugIsend(Integer debugIsend) public void setDebugIsend(Integer debugIsend)
{ {
this.debugIsend = debugIsend; this.debugIsend = debugIsend;
} }
public Integer getDebugIsend() public Integer getDebugIsend()
{ {
return debugIsend; return debugIsend;
} }
public void setLogLevel(String logLevel) public void setLogLevel(String logLevel)
{ {
this.logLevel = logLevel; this.logLevel = logLevel;
} }
public String getLogLevel() public String getLogLevel()
{ {
return logLevel; return logLevel;
} }
public void setLogDetail(String logDetail) public void setLogDetail(String logDetail)
{ {
this.logDetail = logDetail; this.logDetail = logDetail;
} }
public String getLogDetail() public String getLogDetail()
{ {
return logDetail; return logDetail;
} }
public String toString() { public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
.append("debugId", getDebugId()) .append("debugId", getDebugId())
.append("caseId", getCaseId()) .append("caseId", getCaseId())
.append("userId", getUserId()) .append("userId", getUserId())
.append("debugIsend", getDebugIsend()) .append("caseType",getCaseType())
.append("logLevel", getLogLevel()) .append("debugIsend", getDebugIsend())
.append("logDetail", getLogDetail()) .append("logLevel", getLogLevel())
.toString(); .append("logDetail", getLogDetail())
} .toString();
}
} }

View File

@ -1,5 +1,6 @@
package com.luckyframe.project.testmanagmt.projectCase.domain; package com.luckyframe.project.testmanagmt.projectCase.domain;
import com.luckyframe.framework.aspectj.lang.annotation.Excel;
import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle; import org.apache.commons.lang3.builder.ToStringStyle;
@ -18,26 +19,36 @@ public class ProjectCaseSteps extends BaseEntity
/** 步骤ID */ /** 步骤ID */
private Integer stepId; private Integer stepId;
/** 用例ID */ /** 用例ID */
@Excel(name = "用例ID")
private Integer caseId; private Integer caseId;
/** 项目ID */ /** 项目ID */
@Excel(name = "项目ID")
private Integer projectId; private Integer projectId;
/** 步骤序号 */ /** 步骤序号 */
private Integer stepSerialNumber; private Integer stepSerialNumber;
/** 包路径|定位路径 */ /** 包路径|定位路径 */
@Excel(name = "包路径|定位路径")
private String stepPath; private String stepPath;
/** 方法名|操作 */ /** 方法名|操作 */
@Excel(name = "方法名|操作")
private String stepOperation; private String stepOperation;
/** 参数 */ /** 参数 */
@Excel(name = "参数")
private String stepParameters; private String stepParameters;
/** 步骤动作 */ /** 步骤动作 */
@Excel(name = "步骤动作")
private String action; private String action;
/** 预期结果 */ /** 预期结果 */
@Excel(name = "预期结果")
private String expectedResult; private String expectedResult;
/** 默认类型 0 HTTP接口 1 Web UI 2 API驱动 3移动端 */ /** 默认类型 0 HTTP接口 1 Web UI 2 API驱动 3移动端 */
@Excel(name = "默认类型")
private Integer stepType; private Integer stepType;
/** 扩展字段可用于备注、存储HTTP模板等 */ /** 扩展字段可用于备注、存储HTTP模板等 */
@Excel(name = "扩展字段")
private String extend; private String extend;
/** 备注字段,用于接口类型的步骤的备注 */ /** 备注字段,用于接口类型的步骤的备注 */
@Excel(name = "备注字段")
private String stepRemark; private String stepRemark;
public void setStepId(Integer stepId) public void setStepId(Integer stepId)

View File

@ -0,0 +1,118 @@
package com.luckyframe.rc;
import com.luckyframe.rc.entity.ElementAction;
import org.springframework.web.multipart.MultipartFile;
import java.awt.*;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
public class ReadTxt {
//存放控件集合
ArrayList<ElementAction> elementActionArrayList;
//剪贴板字符串
String clipStr = "";
public void getStrFromClip(){
Clipboard clipct = Toolkit.getDefaultToolkit().getSystemClipboard();
// 获取剪切板中的内容
Transferable clipTf= clipct.getContents(null);
if (clipTf!=null)
{
// 检查内容是否是文本类型
if (clipTf.isDataFlavorSupported(DataFlavor.stringFlavor)) {
try {
clipStr = (String) clipTf.getTransferData(DataFlavor.stringFlavor);
} catch (Exception e) {
e.printStackTrace();
}
}
}
System.out.println(clipStr);
}
/**
*
* @param file 录制好的app自动化测试脚本文件
* @return
* @throws IOException
*/
public List<ElementAction> Extract(MultipartFile file) throws IOException {
//初始化
elementActionArrayList=new ArrayList<>();
//读取脚本
if (file.isEmpty() || file.getSize() <= 0) {
file = null;
}
BufferedReader reader=new BufferedReader(new InputStreamReader(file.getInputStream(),"utf-8"));
String line;
//按行读取如果还没有读到尾一直执行
while ((line= reader.readLine())!=null){
//如果读到的这行是获取控件
if(line.contains("findElementBy")) {
if (!line.contains("//")) {
ElementAction elementAction = new ElementAction();
//按格式截取相应的值存入集合
int index = line.indexOf("findElement");
String way;
//判断获取控件的方式
if (line.substring(index, line.indexOf("\"") - 1).contains("Id"))
way = "id";
else
way = "xpath";
way = way + "=" + line.substring(line.indexOf("\"") + 1, line.lastIndexOf("\""));
elementAction.setAccess(way);
//获取控件之后必为操作
line = reader.readLine();
elementAction.setAction(line.substring(line.indexOf(".") + 1, line.indexOf("(")));
if (line.contains("\""))
elementAction.setActionValue(line.substring(line.indexOf("\"") + 1, line.lastIndexOf("\"")));
elementActionArrayList.add(elementAction);
}
}
//如果读到这行是滑动操作
else if(line.contains("(new TouchAction(driver))")) {
line =reader.readLine();
if(line.contains(".press"))
{
String actionValue="";
actionValue=actionValue+line.substring(line.indexOf(":")+2,line.indexOf(",")+1)+line.substring(line.lastIndexOf(":")+2,line.lastIndexOf("}"))+"|";
line =reader.readLine();
if(line.contains(".moveto"))
{
line=line.substring(line.indexOf(":")+2);
actionValue=actionValue+line.substring(0,line.indexOf(":"))+","+line.substring(line.lastIndexOf(":")+2,line.lastIndexOf("}"));
ElementAction elementAction=new ElementAction();
elementAction.setAction("moveto");
elementAction.setActionValue(actionValue);
elementActionArrayList.add(elementAction);
}
}
}
}
for (ElementAction elementAction : elementActionArrayList) {
System.out.println(elementAction);
}
reader.close();
return elementActionArrayList;
}
}

View File

@ -0,0 +1,127 @@
package com.luckyframe.rc;
import com.luckyframe.rc.entity.RcWebCaseSteps;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.multipart.MultipartFile;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.LinkedList;
@Slf4j
public class Readfile {
/**
* 保存活动
* @param file 读取录制好的web自动化测试脚本文件内容
* @throws IOException
*/
public LinkedList<RcWebCaseSteps> saveAction(MultipartFile file) throws IOException {
LinkedList<RcWebCaseSteps> rcWebCaseStepsLinkedList=new LinkedList<>();
if (file.isEmpty() || file.getSize() <= 0) {
file = null;
}
BufferedReader reader=new BufferedReader(new InputStreamReader(file.getInputStream(),"utf-8"));
StringBuilder StringBuilder=new StringBuilder();//用来显示内容用的StringBuilder
String line;
//按行读取内容如果还没有读到尾一直执行
StringBuilder.append("\n");
int n=0;
int start = 99999999;
int end;
LinkedList<String> var=new LinkedList<>();
while ((line= reader.readLine())!=null){
StringBuilder.append(line).append("\n");
var.add(line);
n++;
line=line.trim();
if(line.startsWith("driver.get(")) {
//打开网页
log.info("打开网页");
RcWebCaseSteps rcWebCaseSteps=new RcWebCaseSteps();
rcWebCaseSteps.setStepOperation("open");
//解析网页路径
String url;
url=line.substring(line.indexOf("driver.get(")+"driver.get(".length(),line.indexOf(")")).replace("\"","");
rcWebCaseSteps.setStepParameters(url);
rcWebCaseStepsLinkedList.add(rcWebCaseSteps);
rcWebCaseSteps=null;
}else if (line.startsWith("driver.findElement(")){
//查找元素
if (line.contains("By.id(")){
//通过id查找
log.info("通过id查找");
String id;
id=line.substring(line.indexOf("By.id(")+"By.id(".length(),line.indexOf(")")).replace("\"","");
log.info("id="+id);
RcWebCaseSteps rcWebCaseSteps=new RcWebCaseSteps();
rcWebCaseSteps.setStepPath("id="+id);
//解析操作
if(line.endsWith(".click();")) {
rcWebCaseSteps.setStepOperation("click");
}else if(line.contains(".sendKeys(")){
rcWebCaseSteps.setStepOperation("sendkeys");
//解析SendKeys的value
String param=line.substring(line.indexOf(".sendKeys(")+".sendKeys(".length(),line.indexOf(";")-1).replace("\"","");
rcWebCaseSteps.setStepParameters(param);
}
rcWebCaseStepsLinkedList.add(rcWebCaseSteps);
rcWebCaseSteps=null;
}else if (line.contains("By.cssSelector")){
//通过css选择器查找
log.info("通过css查找");
String id;
id=line.substring(line.indexOf("By.cssSelector(")+"By.cssSelector(".length(),line.indexOf("\"",("driver.findElement(By.cssSelector(\"").length())).replace("\"","");
log.info("cssselector="+id);
RcWebCaseSteps rcWebCaseSteps=new RcWebCaseSteps();
rcWebCaseSteps.setStepPath("cssselector="+id);
//解析操作
if(line.endsWith(".click();")) {
rcWebCaseSteps.setStepOperation("click");
}else if(line.contains(".sendKeys(")){
rcWebCaseSteps.setStepOperation("sendkeys");
//解析SendKeys的value
String param=line.substring(line.indexOf(".sendKeys(")+".sendKeys(".length(),line.indexOf(";")-1).replace("\"","");
rcWebCaseSteps.setStepParameters(param);
}
rcWebCaseStepsLinkedList.add(rcWebCaseSteps);
rcWebCaseSteps=null;
}
}else if(line.startsWith("driver.manage().window().setSize(")){
//设置浏览器大小
log.info("设置浏览器大小");
RcWebCaseSteps rcWebCaseSteps=new RcWebCaseSteps();
rcWebCaseSteps.setStepOperation("windowsetsize");
//解析窗口大小
String operationValue;
operationValue=line.substring("driver.manage().window().setSize(new Dimension(".length(),line.indexOf(")","driver.manage().window().setSize(new Dimension(".length()));
rcWebCaseSteps.setStepParameters(operationValue);
rcWebCaseStepsLinkedList.add(rcWebCaseSteps);
rcWebCaseSteps=null;
}else if(line.startsWith("driver.switchTo().window")){
//切换窗口句柄
log.info("切换窗口句柄");
RcWebCaseSteps rcWebCaseSteps=new RcWebCaseSteps();
rcWebCaseSteps.setStepOperation("switchtowindow");
rcWebCaseStepsLinkedList.add(rcWebCaseSteps);
rcWebCaseSteps=null;
}else if (line.startsWith("{")){
start=n;
}else if(line.startsWith("}")){
end=n;
if (end>start){
for (int i=0;i<end-start;i++){
var.get((start-1)+i);
}
start=99999999;//初始化
}
}
}
log.info(StringBuilder.toString());
return rcWebCaseStepsLinkedList;
}
}

View File

@ -0,0 +1,33 @@
package com.luckyframe.rc.entity;
import lombok.Getter;
import lombok.Setter;
/**
* 元素行为
*/
@Getter
@Setter
public class ElementAction {
/**
* access
* action
* actionValue
*/
String access;
String action;
String actionValue;
@Override
public String toString() {
return "ElementAction{" +
"access='" + access + '\'' +
", action='" + action + '\'' +
", actionValue='" + actionValue + '\'' +
'}';
}
}

View File

@ -0,0 +1,30 @@
package com.luckyframe.rc.entity;
import lombok.Getter;
import lombok.Setter;
/**
* WEB自动化测试用例步骤
* @author lifengyang
*/
@Getter
@Setter
public class RcWebCaseSteps {
/** 包路径|定位路径 */
private String stepPath;
/** 方法名|操作 */
private String stepOperation;
/** 参数 */
private String stepParameters;
/** 步骤动作 */
private String action;
/** 预期结果 */
private String expectedResult;
/** 默认类型 0 HTTP接口 1 Web UI 2 API驱动 3移动端 */
private Integer stepType;
/** 扩展字段可用于备注、存储HTTP模板等 */
private String extend;
/** 备注字段,用于接口类型的步骤的备注 */
private String stepRemark;
}

View File

@ -83,8 +83,6 @@
var taskExecutePrefix = ctx + "testexecution/taskExecute"; var taskExecutePrefix = ctx + "testexecution/taskExecute";
$(function() { $(function() {
//初始化子表格(无限循环) //初始化子表格(无限循环)
const InitSubTable = function (index, row, $detail) { const InitSubTable = function (index, row, $detail) {
const cur_table = $detail.html('<table style="word-break:break-all;"></table>').find('table'); const cur_table = $detail.html('<table style="word-break:break-all;"></table>').find('table');
@ -125,11 +123,11 @@
cellStyle: function (value, row, index, field) { cellStyle: function (value, row, index, field) {
if (row.logGrade != "info") { if (row.logGrade != "info") {
return { return {
css: {"color": "#ff0000"} css: {"color": "#ff0000","class":"test1"}
}; };
} else { } else {
return { return {
css: {"color": "#00bf5f"} css: {"color": "#00bf5f","class":"test2"}
}; };
} }
} }
@ -153,7 +151,7 @@
return '<font style="color:#ff0000">' + value + '</font>&nbsp;&nbsp;&nbsp;&nbsp;' + return '<font style="color:#ff0000">' + value + '</font>&nbsp;&nbsp;&nbsp;&nbsp;' +
'<a href="#" onclick="updateStep(' + row.logId + ')">同步结果</a> '; '<a href="#" onclick="updateStep(' + row.logId + ')">同步结果</a> ';
} else { } else {
return '<font style="color:#ff0000">' + value + '</font>'; return '<font style="color:#ff0000">' + value + '</font>';
} }
} else { } else {
return '<font style="color:#00bf5f">' + value + '</font>'; return '<font style="color:#00bf5f">' + value + '</font>';
@ -165,10 +163,9 @@
} }
},], },],
//无线循环取子表,直到子表里面没有记录 //无线循环取子表,直到子表里面没有记录
onExpandRow: function (index, row, $Subdetail) { // onExpandRow: function (index, row, $Subdetail) {
oInit.InitSubTable(index, row, $Subdetail); // oInit.InitSubTable(index, row, $Subdetail);
}, // },
}); });
}; };
var options = { var options = {
@ -215,17 +212,20 @@
{ {
field : 'caseId', field : 'caseId',
title : '用例ID', title : '用例ID',
visible: false width : '5%',
visible: true
}, },
{ {
field : 'taskId', field : 'taskId',
title : '任务ID', title : '任务ID',
visible: false width : '5%',
visible: true
}, },
{ {
field : 'projectId', field : 'projectId',
title : '项目ID', title : '项目ID',
visible: false width : '5%',
visible: true
}, },
{ {
field : 'caseSign', field : 'caseSign',
@ -236,7 +236,7 @@
{ {
field : 'caseName', field : 'caseName',
title : '用例名称', title : '用例名称',
width : '50%', width : '20%',
class : 'myTDLengthHidden' class : 'myTDLengthHidden'
}, },
{ {
@ -278,7 +278,22 @@
return '<span style="color:#9966FF">未执行</span>'; return '<span style="color:#9966FF">未执行</span>';
} }
} }
}], },
//修改点
{
field : 'failureReason',
title : '失败原因',
width : '15%',
id:'myTDLengthHiddenFy',
class : 'myTDLengthHidden',
formatter : function(value,
row, index) {
var innerText = getFailedInfo(row.taskCaseId,'error');
return '<span style="color:#ff0000;word-break:break-all;white-space:pre-wrap">'+ innerText+'</span>';
}
}],
//注册加载子表的事件。注意下这里的三个参数! //注册加载子表的事件。注意下这里的三个参数!
onExpandRow : function(index, row, $detail) { onExpandRow : function(index, row, $detail) {
InitSubTable(index, row, $detail); InitSubTable(index, row, $detail);
@ -286,8 +301,11 @@
}; };
$.table.init(options); $.table.init(options);
}); });
/* 同步测试结果到用例步骤 */ /* 同步测试结果到用例步骤 */
function updateStep(logId){ function updateStep(logId){
$.modal.confirm("确认要同步测试结果到步骤中吗?", function() { $.modal.confirm("确认要同步测试结果到步骤中吗?", function() {
@ -296,7 +314,26 @@
$.operate.submit(url, "post", "json", data); $.operate.submit(url, "post", "json", data);
}); });
} }
/*获取失败原因*/
function getFailedInfo(taskCaseId,error){
var url =logPrefix + "/list";
var options = "";
var data = {"taskCaseId": taskCaseId,"errorInfo": error};
$.ajaxSettings.async = false;
$.getJSON(url, data, function call(result) {
/*设置新的调度列表*/
$.each(result, function(i, node){
options = options + node.logDetail ;
});
});
return options;
}
/* 运行所有非成功用例 */ /* 运行所有非成功用例 */
function run(){ function run(){
$.modal.confirm("确认要运行所有非成功用例吗?", function() { $.modal.confirm("确认要运行所有非成功用例吗?", function() {
@ -337,12 +374,12 @@
/*设置新的调度列表*/ /*设置新的调度列表*/
$.each(result, function(i, node){ $.each(result, function(i, node){
options += "<option value='"+node.taskId+"'>"+node.taskName+"</option>"; options += "<option value='"+node.taskId+"'>"+node.taskName+"</option>";
}); });
$("#taskId").html(options); $("#taskId").html(options);
}); });
} }
/*弹出层展示图片*/ /*弹出层展示图片*/
function showPlanCase(logId) { function showPlanCase(logId) {
var url = prefix+"/showImage.do?logId="+logId; var url = prefix+"/showImage.do?logId="+logId;
$.modal.openViewFull($.table._option.childrenModalName, url, null, null); $.modal.openViewFull($.table._option.childrenModalName, url, null, null);

View File

@ -105,7 +105,8 @@
{ {
field : 'schedulingId', field : 'schedulingId',
title : '调度ID', title : '调度ID',
visible: false, visible: true,
width : '5%',
sortable: true sortable: true
}, },
{ {
@ -116,7 +117,7 @@
{ {
field : 'schedulingName', field : 'schedulingName',
title : '调度名称', title : '调度名称',
width : '20%', width : '15%',
formatter : function(value, formatter : function(value,
row, index) { row, index) {
return '<a href="#" onclick="taskExcute('+row.schedulingId+')">'+ value + '</a> '; return '<a href="#" onclick="taskExcute('+row.schedulingId+')">'+ value + '</a> ';

View File

@ -7,12 +7,21 @@
<form class="form-horizontal m" id="form-debugCase" th:object="${projectCaseDebug}"> <form class="form-horizontal m" id="form-debugCase" th:object="${projectCaseDebug}">
<input id="caseId" th:field="*{caseId}" type="hidden"> <input id="caseId" th:field="*{caseId}" type="hidden">
<input id="userId" th:field="*{userId}" type="hidden"> <input id="userId" th:field="*{userId}" type="hidden">
<div class="form-group"> <input id="caseType" th:field="*{caseType}" type="hidden"><!--修改点-->
<div class="form-group" id="divBrowserType" style="display:none">
<label class="col-sm-3 control-label">浏览器类型:</label>
<div class="col-sm-8">
<label class="radio-box"> <input type="radio" th:field="*{browserType}" value="0" /> IE </label>
<label class="radio-box"> <input type="radio" th:field="*{browserType}" value="1" /> 火狐 </label>
<label class="radio-box"> <input type="radio" th:field="*{browserType}" value="2" th:checked="true"/> 谷歌 </label>
<label class="radio-box"> <input type="radio" th:field="*{browserType}" value="3" /> Edge </label>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">客户端:</label> <label class="col-sm-3 control-label">客户端:</label>
<div class="col-sm-8"> <div class="col-sm-8">
<select class="form-control" id="clientId" th:field="*{clientId}" onChange="getDriverPath()"> <select class="form-control" id="clientId" th:field="*{clientId}" onChange="getDriverPath()">
<option th:each="client:${clients}" th:value="${client.clientId}" <option th:each="client:${clients}" th:value="${client.clientId}" th:text="【+${client.clientName}+】+${client.clientIp}+${client.statusStr}"></option>
th:text="【+${client.clientName}+】+${client.clientIp}+${client.statusStr}"></option>
</select> </select>
</div> </div>
</div> </div>
@ -113,6 +122,14 @@
$("#driverPath option[index='1']").remove(); $("#driverPath option[index='1']").remove();
} }
} }
//修改点
//控制BrowserType显示
if($("#caseType").attr("value")==1){
$("#divBrowserType").css("display","block");
}else {
$("#divBrowserType").css("display", "none");
};
</script> </script>
</body> </body>
</html> </html>

View File

@ -2,7 +2,188 @@
<html lang="zh" xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.pollix.at/thymeleaf/shiro"> <html lang="zh" xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
<meta charset="utf-8"> <meta charset="utf-8">
<head th:include="include :: header"></head> <head th:include="include :: header"></head>
<!--修改点-->
<style>
.upload_dialog_div{
position:fixed;
left:0px;
right:0px;
top:0px;
bottom:0px;
overflow:auto;
visibility:hidden;
background-color: rgba(60,60,60,0.5);
z-index:99;
}
.style_content_div{
position:relative;
margin:auto;
margin-top:160px;
width:400px;
height:160px;
background: #ffffff;
}
.style_content_upper_div{
position:absolute;
left:0px;
top:0px;
width:400px;
height:100px;
background:#ffffff;
}
.style_content_lower_div{
position:absolute;
left:0px;
top:100px;
width:400px;
height:60px;
background:#ffffff;
}
.style_content_file_div{
position:absolute;
left:15px;
top:20px;
width:380px;
height:60px;
}
.style_file_span{
float:left;
width:120px;
height:36px;
font-size:24px;
text-align:right;
}
.style_file_content{
margin-top:5px;
}
.style_content_prog_div{
position:absolute;
left:18px;
top:57px;
width:360px;
height:40px;
}
.style_prog_span_hit{
color:#ff0000;
}
.style_prog_content{
width:360px;
visibility:hidden;
}
</style>
<script>
function createHttpRequest()
{
var xmlHttp=null;
try{
// Firefox, Opera 8.0+, Safari
xmlHttp=new XMLHttpRequest();
}catch (e){
// Internet Explorer
try{
xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");
}catch (e){
try{
xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
}catch (e){
alert("您的浏览器不支持AJAX");
}
}
}
return xmlHttp;
}
function uploadFileToServer(){
var caseId = $($("tr[class='selected']").find('td')[4]).find("a").attr("pt_caseId");
var projectId = $($("tr[class='selected']").find('td')[4]).find("a").attr("pt_projectId");
var stepType= $($("tr[class='selected']").find('td')[4]).find("a").attr("pt_caseType");
// alert(caseId+" "+projectId+" "+stepType);
var uploadFile = document.getElementById("upload_file_id");
var uploadTip = document.getElementById("upload_tip_id");
var uploadProgress = document.getElementById("upload_progress_id");
if(uploadFile.value==""){
uploadTip.innerText="请选择一个文件";
}else if(uploadFile.files[0].size>0 &&uploadFile.files[0].size<(100*1024*1024)){
try{
if(window.FileReader){
var fReader = new FileReader();
var xhreq=createHttpRequest();
var form = new FormData();
form.append('caseId',caseId);
form.append('projectId', projectId);
form.append('stepType', stepType);
form.append('file', uploadFile.files[0]);
xhreq.onreadystatechange=function(){
if(xhreq.readyState==4){
if(xhreq.status==200){
uploadTip.innerText="文件上传成功";
setTimeout(function(){
hideUploadDialog()
},2000); //2秒后隐藏
}else{
uploadTip.innerText="文件上传失败了";
}
}
}
fReader.onload=function(e){
xhreq.open("POST","/testmanagmt/RecordController/insert",true);
xhreq.setRequestHeader("ContentType", "multipart/form-data"); //流类型
xhreq.send(form);
}
fReader.onprogress = function(e){
uploadProgress.value = e.loaded*100/e.total;
}
fReader.readAsArrayBuffer(uploadFile.files[0]);
uploadProgress.style.visibility="visible";
uploadProgress.value = 0;
}else{
uploadTip.innerText="浏览器不支持上传文件";
}
}catch(e){
uploadTip.innerText="文件上传失败";
}
}else{
uploadTip.innerText="文件不符合要求";
}
}
function showUploadDialog(){
var up_dialog=document.getElementById("upload_dialog");
document.getElementById("upload_tip_id").innerText="请选择要上传的文件";
document.getElementById("upload_progress_id").style.visibility="hidden";
up_dialog.style.visibility="visible";
}
function hideUploadDialog(){
var up_dialog=document.getElementById("upload_dialog");
document.getElementById("upload_progress_id").style.visibility="hidden";
up_dialog.style.visibility="hidden";
}
</script>
<body class="gray-bg"> <body class="gray-bg">
<!--修改点-->
<div id="upload_dialog" class="upload_dialog_div">
<div class="style_content_div">
<div class="style_content_upper_div">
<div class="style_content_file_div">
<span class="style_file_span"> 文件:</span>
<input class="style_file_content" type="file" id="upload_file_id"/>
</div>
<div class="style_content_prog_div">
<span class="style_prog_span_hit" id="upload_tip_id"> 请选择要上传的文件 </span>
<progress class="style_prog_content" id="upload_progress_id" value="0" max="100"></progress>
</div>
</div>
<div class="style_content_lower_div">
<div class="layui-layer-btn layui-layer-btn-">
<a class="layui-layer-btn1" onclick="hideUploadDialog()">取消</a>
<a class="layui-layer-btn0" onclick="uploadFileToServer()">确认</a>
</div>
</div>
</div>
</div>
<div class="container-div"> <div class="container-div">
<div class="row"> <div class="row">
@ -88,6 +269,12 @@
<i class="fa fa-list-ol"></i> 用例步骤 <i class="fa fa-list-ol"></i> 用例步骤
</a> </a>
</shiro:hasPermission> </shiro:hasPermission>
<!--修改点-->
<shiro:hasPermission name="testmanagmt:projectCase:import">
<a class="btn btn-info btn-import" onclick="showUploadDialog()">
<span class="glyphicon glyphicon-import" aria-hidden="true"></span> 用例步骤导入
</a>
</shiro:hasPermission>
<shiro:hasPermission name="testmanagmt:projectCase:remove"> <shiro:hasPermission name="testmanagmt:projectCase:remove">
<a class="btn btn-danger btn-del btn-del disabled" onclick="$.operate.removeAll()"> <a class="btn btn-danger btn-del btn-del disabled" onclick="$.operate.removeAll()">
<i class="fa fa-remove"></i> 删除 <i class="fa fa-remove"></i> 删除
@ -95,7 +282,12 @@
</shiro:hasPermission> </shiro:hasPermission>
<shiro:hasPermission name="testmanagmt:projectCase:export"> <shiro:hasPermission name="testmanagmt:projectCase:export">
<a class="btn btn-warning" onclick="$.table.exportExcel('formId')"> <a class="btn btn-warning" onclick="$.table.exportExcel('formId')">
<i class="fa fa-download"></i> 导出 <span class="glyphicon glyphicon-export" aria-hidden="true"></span> 导出用例列表
</a>
</shiro:hasPermission>
<shiro:hasPermission name="testmanagmt:projectCase:exportcasestep">
<a class="btn btn-warning" onclick="exportcasestepExcel()">
<span class="glyphicon glyphicon-export" aria-hidden="true"></span> 导出用例步骤
</a> </a>
</shiro:hasPermission> </shiro:hasPermission>
</div> </div>
@ -173,7 +365,11 @@
width: '10%', width: '10%',
class: 'myTDLengthHidden', class: 'myTDLengthHidden',
formatter: function (value, row, index) { formatter: function (value, row, index) {
return '<a class="btn btn-info btn-edit" onclick="$.operate.customFull('+row.caseId+')">'+value+'</a>'; return '<a class="btn btn-info btn-edit" '+
'pt_caseId="'+row.caseId+'" ' +
'pt_projectId="'+row.projectId+'" '+
'pt_caseType="'+row.caseType+'" '+
'onclick="$.operate.customFull('+row.caseId+')">'+value+'</a>';
} }
}, },
{ {
@ -551,6 +747,28 @@
initializeModuleTree(); initializeModuleTree();
$.form.reset(); $.form.reset();
} }
/* 导出用例步骤*/
function exportcasestepExcel() {
$.modal.loading("正在导出数据,请稍后...");
var caseId = $($("tr[class='selected']").find('td')[4]).find("a").attr("pt_caseId");
$.ajax({
type: "POST",
url: stepsPrefix + "/export",
data: {caseId:caseId},
async: false,
error: function (result) {
$.modal.alertError(result.msg);
$.modal.closeLoading();
},
success: function (result) {
if (result.code == web_status.SUCCESS) {
window.location.href = ctx + "common/download?fileName=" + result.msg + "&delete=" + true;
}
$.modal.closeLoading();
}
});
}
</script> </script>
</body> </body>
</html> </html>

View File

@ -87,6 +87,9 @@
<div class="col-lg-4 text-center" style="width: 100%"> <div class="col-lg-4 text-center" style="width: 100%">
<button class="btn btn-info" id="debugButton" onclick="showDebugModal()" type="button" style="padding-left: 36px;padding-right: 36px;" th:if="${projectCase.caseType==0||projectCase.caseType==2}">&nbsp;&nbsp;&nbsp;&nbsp;</button> <button class="btn btn-info" id="debugButton" onclick="showDebugModal()" type="button" style="padding-left: 36px;padding-right: 36px;" th:if="${projectCase.caseType==0||projectCase.caseType==2}">&nbsp;&nbsp;&nbsp;&nbsp;</button>
</div> </div>
<div class="col-lg-4 text-center" style="width: 100%">
<button class="btn btn-info" id="debugButton2" onclick="showDebugModal()" type="button" style="padding-left: 36px;padding-right: 36px;" th:if="${projectCase.caseType==1}">&nbsp;&nbsp;&nbsp;&nbsp;</button><!--修改点-->
</div>
</div> </div>
</div> </div>
@ -321,12 +324,14 @@
/*不同的校验规则,不同的错误提示*/ /*不同的校验规则,不同的错误提示*/
$.validator.messages.required = "HTTP接口必填"; $.validator.messages.required = "HTTP接口必填";
return true; return true;
}else if(stepType=="2" && $("#expectedResult"+num).val()==""){ }else {
$.validator.messages.required = "API接口必填";
return true;
}else{
return false; return false;
} }
//修改点
// else if(stepType=="2" && $("#expectedResult"+num).val()==""){
// $.validator.messages.required = "API接口必填";
// return true;
// }
} }
}, },
extend:{ extend:{