feat(UI自动化): 新增元素库导入、元素引用删除提示

--story=1007525 --user=刘瑶 【UI测试】元素库优化 https://www.tapd.cn/55049933/s/1194247
This commit is contained in:
nathan.liu 2022-06-29 16:51:42 +08:00 committed by zhangdahai112
parent 87d9b8fcfb
commit cb707e69fb
21 changed files with 350 additions and 24 deletions

View File

@ -9,4 +9,5 @@ import lombok.Data;
public class ModuleNode extends TestCaseNode {
private Integer caseNum;
private String protocol;
private String modulePath;
}

View File

@ -21,6 +21,8 @@ public class UiElement implements Serializable {
private String createUser;
private String updateUser;
private String versionId;
private String refId;

View File

@ -0,0 +1,25 @@
package io.metersphere.base.domain;
import lombok.Data;
import java.io.Serializable;
@Data
public class UiElementReference implements Serializable {
private String id;
private String elementId;
private String elementModuleId;
private String scenarioId;
private String projectId;
private Long createTime;
private static final long serialVersionUID = 1L;
}

View File

@ -0,0 +1,19 @@
package io.metersphere.base.domain;
import lombok.Data;
import java.io.Serializable;
@Data
public class UiTaskRefresh implements Serializable {
private String id;
private String taskKey;
private Integer taskStatus;
private long createTime;
private static final long serialVersionUID = 1L;
}

View File

@ -10,6 +10,7 @@
<result column="location_type" jdbcType="VARCHAR" property="locationType" />
<result column="location" jdbcType="VARCHAR" property="location" />
<result column="create_user" jdbcType="VARCHAR" property="createUser" />
<result column="update_user" jdbcType="VARCHAR" property="updateUser" />
<result column="version_id" jdbcType="VARCHAR" property="versionId" />
<result column="ref_id" jdbcType="VARCHAR" property="refId" />
<result column="order" jdbcType="BIGINT" property="order" />
@ -77,7 +78,7 @@
</where>
</sql>
<sql id="Base_Column_List">
id, num, module_id, project_id, `name`, location_type, `location`, create_user, version_id,
id, num, module_id, project_id, `name`, location_type, `location`, create_user, update_user, version_id,
ref_id, `order`, latest, description, create_time, update_time
</sql>
<select id="selectByExample" parameterType="io.metersphere.base.domain.UiElementExample" resultMap="BaseResultMap">
@ -113,12 +114,12 @@
<insert id="insert" parameterType="io.metersphere.base.domain.UiElement">
insert into ui_element (id,num, module_id,
project_id, `name`, location_type,
`location`, create_user, version_id,
`location`, create_user, update_user, version_id,
ref_id, `order`, latest, description,
create_time, update_time)
values (#{id,jdbcType=VARCHAR}, #{num,jdbcType=INTEGER}, #{moduleId,jdbcType=VARCHAR},
#{projectId,jdbcType=VARCHAR}, #{name,jdbcType=VARCHAR}, #{locationType,jdbcType=VARCHAR},
#{location,jdbcType=VARCHAR}, #{createUser,jdbcType=VARCHAR}, #{versionId,jdbcType=VARCHAR},
#{location,jdbcType=VARCHAR}, #{createUser,jdbcType=VARCHAR}, #{updateUser,jdbcType=VARCHAR}, #{versionId,jdbcType=VARCHAR},
#{refId,jdbcType=VARCHAR}, #{order,jdbcType=BIGINT}, #{latest,jdbcType=BIT}, #{description,jdbcType=VARCHAR},
#{createTime,jdbcType=BIGINT}, #{updateTime,jdbcType=BIGINT})
</insert>
@ -149,6 +150,9 @@
<if test="createUser != null">
create_user,
</if>
<if test="updateUser != null">
update_user,
</if>
<if test="versionId != null">
version_id,
</if>
@ -196,6 +200,9 @@
<if test="createUser != null">
#{createUser,jdbcType=VARCHAR},
</if>
<if test="updateUser != null">
#{updateUser,jdbcType=VARCHAR},
</if>
<if test="versionId != null">
#{versionId,jdbcType=VARCHAR},
</if>
@ -252,6 +259,9 @@
<if test="record.createUser != null">
create_user = #{record.createUser,jdbcType=VARCHAR},
</if>
<if test="record.updateUser != null">
update_user = #{record.updateUser,jdbcType=VARCHAR},
</if>
<if test="record.versionId != null">
version_id = #{record.versionId,jdbcType=VARCHAR},
</if>
@ -288,6 +298,7 @@
location_type = #{record.locationType,jdbcType=VARCHAR},
`location` = #{record.location,jdbcType=VARCHAR},
create_user = #{record.createUser,jdbcType=VARCHAR},
update_user = #{record.updateUser,jdbcType=VARCHAR},
version_id = #{record.versionId,jdbcType=VARCHAR},
ref_id = #{record.refId,jdbcType=VARCHAR},
`order` = #{record.order,jdbcType=BIGINT},
@ -323,6 +334,9 @@
<if test="createUser != null">
create_user = #{createUser,jdbcType=VARCHAR},
</if>
<if test="updateUser != null">
update_user = #{updateUser,jdbcType=VARCHAR},
</if>
<if test="versionId != null">
version_id = #{versionId,jdbcType=VARCHAR},
</if>
@ -356,6 +370,7 @@
location_type = #{locationType,jdbcType=VARCHAR},
`location` = #{location,jdbcType=VARCHAR},
create_user = #{createUser,jdbcType=VARCHAR},
update_user = #{updateUser,jdbcType=VARCHAR},
version_id = #{versionId,jdbcType=VARCHAR},
ref_id = #{refId,jdbcType=VARCHAR},
`order` = #{order,jdbcType=BIGINT},

View File

@ -0,0 +1,22 @@
package io.metersphere.base.mapper;
import io.metersphere.base.domain.UiElementReference;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface UiElementReferenceMapper {
void batchInsert(@Param("uiElementReferences") List<UiElementReference> uiElementReferences);
List<UiElementReference> listByElementIds(@Param("projectId") String projectId, @Param("scenarioId") String scenarioId, @Param("elementIds") List<String> elementIds, @Param("limit") Integer limit);
void batchDelete(@Param("projectId") String projectId, @Param("scenarioId") String scenarioId, @Param("elementIds") List<String> elementIds);
List<UiElementReference> listByScenarioId(@Param("projectId") String projectId, @Param("scenarioId") String scenarioId);
List<UiElementReference> listByModuleIds(String projectId, List<String> moduleIds, Integer limit);
void batchDeleteWithScenarioIds(@Param("scenarioIds") List<String> scenarioIds);
}

View File

@ -0,0 +1,114 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="io.metersphere.base.mapper.UiElementReferenceMapper">
<delete id="batchDelete">
DELETE FROM
ui_element_reference
<where>
<if test="projectId != null">
AND
project_id = #{projectId}
</if>
<if test="scenarioId != null">
AND
scenario_id = #{scenarioId}
</if>
<if test="elementIds != null and elementIds.size() > 0">
AND
element_id IN
<foreach collection="elementIds" item="elementId" separator="," open="(" close=")">
#{elementId}
</foreach>
</if>
</where>
</delete>
<delete id="batchDeleteWithScenarioIds">
DELETE FROM
ui_element_reference
<where>
<if test="scenarioIds != null and scenarioIds.size() > 0">
AND
scenario_id IN
<foreach collection="scenarioIds" item="scenarioId" separator="," open="(" close=")">
#{scenarioId}
</foreach>
</if>
</where>
</delete>
<insert id="batchInsert" parameterType="java.util.List">
INSERT INTO
ui_element_reference (
id, element_id, element_module_id, scenario_id, project_id, create_time
)
VALUES
<foreach collection="uiElementReferences" item="reference" separator="," >
( #{reference.id}, #{reference.elementId},#{reference.elementModuleId},
#{reference.scenarioId}, #{reference.projectId},#{reference.createTime} )
</foreach>
</insert>
<select id="listByElementIds" resultType="io.metersphere.base.domain.UiElementReference">
SELECT *
FROM
ui_element_reference
<where>
<if test="projectId != null">
AND
project_id = #{projectId}
</if>
<if test="scenarioId != null">
AND
scenario_id = #{scenarioId}
</if>
<if test="elementIds != null and elementIds.size() > 0">
AND
element_id IN
<foreach collection="elementIds" item="elementId" separator="," open="(" close=")">
#{elementId}
</foreach>
</if>
</where>
ORDER BY create_time DESC
<if test="limit != null">
limit #{limit}
</if>
</select>
<select id="listByModuleIds" resultType="io.metersphere.base.domain.UiElementReference">
SELECT *
FROM
ui_element_reference
<where>
<if test="projectId != null">
AND
project_id = #{projectId}
</if>
<if test="moduleIds != null and moduleIds.size() > 0">
AND
element_module_id IN
<foreach collection="moduleIds" item="moduleId" separator="," open="(" close=")">
#{moduleId}
</foreach>
</if>
</where>
ORDER BY create_time DESC
<if test="limit != null">
limit #{limit}
</if>
</select>
<select id="listByScenarioId" resultType="io.metersphere.base.domain.UiElementReference">
SELECT *
FROM
ui_element_reference
WHERE
project_id = #{projectId}
AND
scenario_id = #{scenarioId}
</select>
</mapper>

View File

@ -0,0 +1,11 @@
package io.metersphere.base.mapper;
import io.metersphere.base.domain.UiTaskRefresh;
import org.apache.ibatis.annotations.Param;
public interface UiTaskRefreshMapper {
UiTaskRefresh getByTaskKey(@Param("taskKey") String taskKey);
void insert(UiTaskRefresh uiTaskRefresh);
}

View File

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="io.metersphere.base.mapper.UiTaskRefreshMapper">
<select id="getByTaskKey" resultType="io.metersphere.base.domain.UiTaskRefresh">
SELECT *
FROM
ui_task_refresh
WHERE
task_key = #{taskKey}
</select>
<insert id="insert" parameterType="io.metersphere.base.domain.UiTaskRefresh">
INSERT INTO
ui_task_refresh(
id, task_key, task_status, create_time
)
VALUE(
#{id}, #{taskKey}, #{taskStatus}, #{createTime}
)
</insert>
</mapper>

View File

@ -16,6 +16,8 @@ public interface ExtModuleNodeMapper {
List<ModuleNodeDTO> getNodeTreeByProjectId(@Param("tableName") String tableName, @Param("projectId") String projectId);
List<ModuleNode> getAllNodeTree(@Param("tableName") String tableName);
int updateByPrimaryKeySelective(@Param("tableName") String tableName, @Param("record") ModuleNode record);
int deleteByExample(@Param("tableName") String tableName, @Param("example") TestCaseNodeExample example);
@ -31,4 +33,6 @@ public interface ExtModuleNodeMapper {
ModuleNode selectByPrimaryKey(@Param("tableName") String tableName, @Param("id") String id);
long countByExample(@Param("tableName") String tableName, @Param("example") TestCaseNodeExample example);
List<ModuleNode> selectByModulePath(@Param("tableName") String tableName,@Param("modulePath") String modulePath, @Param("projectId") String projectId);
}

View File

@ -14,6 +14,9 @@
<if test="record.name != null">
`name`,
</if>
<if test="record.modulePath != null">
`module_path`,
</if>
<if test="record.parentId != null">
parent_id,
</if>
@ -43,6 +46,9 @@
<if test="record.name != null">
#{record.name,jdbcType=VARCHAR},
</if>
<if test="record.modulePath != null">
#{record.modulePath,jdbcType=VARCHAR},
</if>
<if test="record.parentId != null">
#{record.parentId,jdbcType=VARCHAR},
</if>
@ -64,11 +70,11 @@
</trim>
</insert>
<insert id="insert">
insert into ${tableName} (id, project_id, `name`,
insert into ${tableName} (id, project_id, `name`, module_path,
parent_id, `level`, create_time,
update_time, pos, create_user
)
values (#{record.id,jdbcType=VARCHAR}, #{record.projectId,jdbcType=VARCHAR}, #{record.name,jdbcType=VARCHAR},
values (#{record.id,jdbcType=VARCHAR}, #{record.projectId,jdbcType=VARCHAR}, #{record.name,jdbcType=VARCHAR}, #{record.modulePath,jdbcType=VARCHAR},
#{record.parentId,jdbcType=VARCHAR}, #{record.level,jdbcType=INTEGER}, #{record.createTime,jdbcType=BIGINT},
#{record.updateTime,jdbcType=BIGINT}, #{record.pos,jdbcType=DOUBLE}, #{record.createUser,jdbcType=VARCHAR}
)
@ -82,6 +88,9 @@
<if test="record.name != null">
`name` = #{record.name,jdbcType=VARCHAR},
</if>
<if test="record.modulePath != null">
`module_path` = #{record.modulePath,jdbcType=VARCHAR},
</if>
<if test="record.parentId != null">
parent_id = #{record.parentId,jdbcType=VARCHAR},
</if>
@ -114,6 +123,7 @@
update ${tableName}
set project_id = #{record.projectId,jdbcType=VARCHAR},
`name` = #{record.name,jdbcType=VARCHAR},
`module_path` = #{record.modulePath,jdbcType=VARCHAR},
parent_id = #{record.parentId,jdbcType=VARCHAR},
`level` = #{record.level,jdbcType=INTEGER},
create_time = #{record.createTime,jdbcType=BIGINT},
@ -136,6 +146,7 @@
distinct
</if>
<include refid="io.metersphere.base.mapper.TestCaseNodeMapper.Base_Column_List" />
,module_path
from ${tableName}
<if test="_parameter != null">
<include refid="Example_Where_Clause" />
@ -156,6 +167,13 @@
where project_id = #{projectId}
order by pos asc
</select>
<select id="getAllNodeTree" resultType="io.metersphere.base.domain.ModuleNode">
select
id, project_id, `name`, parent_id, `level`, create_time, update_time, pos, create_user
,module_path
from ${tableName}
order by pos asc
</select>
<select id="get" resultType="io.metersphere.track.dto.ModuleNodeDTO">
select
<include refid="io.metersphere.base.mapper.TestCaseNodeMapper.Base_Column_List"/>
@ -205,4 +223,15 @@
</foreach>
</where>
</sql>
<select id="selectByModulePath" resultType="io.metersphere.base.domain.ModuleNode" parameterType="io.metersphere.base.domain.ModuleNode">
SELECT
*
FROM
${tableName}
WHERE
project_id = #{projectId}
AND
module_path = #{modulePath}
</select>
</mapper>

View File

@ -68,10 +68,24 @@ public class BaseModuleService extends NodeTreeService<ModuleNodeDTO> {
module.setCreateUser(SessionUtils.getUserId());
double pos = getNextLevelPos(module.getProjectId(), module.getLevel(), module.getParentId());
module.setPos(pos);
module.setModulePath(getModulePath(module));
extModuleNodeMapper.insertSelective(tableName, module);
return module.getId();
}
public String getModulePath(ModuleNode module){
Integer level = module.getLevel();
if( level == null || level <= 1){
return String.format("/%s",module.getName());
}
//获取父级信息
if(StringUtils.isNotBlank(module.getParentId())){
ModuleNode parent = extModuleNodeMapper.selectByPrimaryKey(tableName, module.getParentId());
return parent.getModulePath() + "/" + module.getName();
}
return null;
}
public List<String> getNodes(String nodeId) {
return extModuleNodeMapper.getNodeIdsByPid(tableName, nodeId);
}
@ -338,9 +352,10 @@ public class BaseModuleService extends NodeTreeService<ModuleNodeDTO> {
}
@Override
public String insertNode(String nodeName, String pId, String projectId, Integer level) {
public String insertNode(String nodeName, String pId, String projectId, Integer level, String path) {
ModuleNode moduleNode = new ModuleNode();
moduleNode.setName(nodeName.trim());
moduleNode.setModulePath(path);
moduleNode.setParentId(pId);
moduleNode.setProjectId(projectId);
moduleNode.setCreateTime(System.currentTimeMillis());
@ -384,7 +399,7 @@ public class BaseModuleService extends NodeTreeService<ModuleNodeDTO> {
buildUpdateTestCase(nodeTree, nodeData, updateNodes, "/", "0", 1);
editNodeDataFunc.accept(nodeData);
} else {
buildUpdateModule(nodeTree, updateNodes, "0", 1);
buildUpdateModule(nodeTree, updateNodes, "0", 1, "");
}
updateNodes = updateNodes.stream()
@ -407,19 +422,25 @@ public class BaseModuleService extends NodeTreeService<ModuleNodeDTO> {
}
private void buildUpdateModule(TestCaseNodeDTO rootNode,
List<ModuleNode> updateNodes, String pId, int level) {
List<ModuleNode> updateNodes, String pId, int level, String parentPath) {
checkoutNodeLimit(level);
ModuleNode moduleNode = new ModuleNode();
moduleNode.setId(rootNode.getId());
moduleNode.setLevel(level);
moduleNode.setParentId(pId);
if(level <= 1 && StringUtils.isBlank(parentPath)){
moduleNode.setModulePath("/" + rootNode.getName());
}
else {
moduleNode.setModulePath(parentPath + "/" + rootNode.getName());
}
updateNodes.add(moduleNode);
List<TestCaseNodeDTO> children = rootNode.getChildren();
if (children != null && children.size() > 0) {
for (int i = 0; i < children.size(); i++) {
buildUpdateModule(children.get(i), updateNodes, rootNode.getId(), level + 1);
buildUpdateModule(children.get(i), updateNodes, rootNode.getId(), level + 1, moduleNode.getModulePath());
}
}
}
@ -590,4 +611,8 @@ public class BaseModuleService extends NodeTreeService<ModuleNodeDTO> {
}
return extModuleNodeMapper.selectByExample(tableName, example);
}
public List<ModuleNode> selectByModulePath(ModuleNode node){
return extModuleNodeMapper.selectByModulePath(tableName, node.getModulePath(), node.getProjectId());
}
}

View File

@ -291,7 +291,7 @@ public class NodeTreeService<T extends TreeNodeDTO> {
pid = pathMap.get(path.toString());
level++;
} else {
pid = insertNode(nodeName, pNode == null ? null : pNode.getId(), projectId, level);
pid = insertNode(nodeName, pNode == null ? null : pNode.getId(), projectId, level, path.toString());
pathMap.put(path.toString(), pid);
level++;
}
@ -303,7 +303,7 @@ public class NodeTreeService<T extends TreeNodeDTO> {
pid = pathMap.get(path.toString());
level++;
} else {
pid = insertNode(nextNodeName, pid, projectId, level);
pid = insertNode(nextNodeName, pid, projectId, level, path.toString());
pathMap.put(path.toString(), pid);
level++;
}
@ -360,7 +360,7 @@ public class NodeTreeService<T extends TreeNodeDTO> {
}
public String insertNode(String nodeName, String pId, String projectId, Integer level) {
public String insertNode(String nodeName, String pId, String projectId, Integer level, String path) {
return "";
}

View File

@ -403,7 +403,7 @@ public class TestCaseNodeService extends NodeTreeService<TestCaseNodeDTO> {
}
@Override
public String insertNode(String nodeName, String pId, String projectId, Integer level) {
public String insertNode(String nodeName, String pId, String projectId, Integer level, String path) {
TestCaseNode testCaseNode = new TestCaseNode();
testCaseNode.setName(nodeName.trim());
testCaseNode.setParentId(pId);

@ -1 +1 @@
Subproject commit 952b8ba44820b5ae7b604b6505d66fe89401ec44
Subproject commit ff5b6db69dd600fb7c68db33256e01efdd51e705

View File

@ -380,3 +380,11 @@ name_already_exists_in_module=Name already exists in same module
rerun_warning=The current report is being rerun
report_warning=Report Type and Report ID cannot be empty
report_type_error=report type error
#ui 元素库
ui_element_name=Name
ui_element_locator=ElementLocator
ui_element_locator_type=LocatorType
ui_element_import_template_name=Ui_element_templates
ui_element_import_template_sheet=Template
ui_element_already_exists_excel=There are duplicate data in the import file
ui_element_already_exists_data=An element with the same name already exists

View File

@ -379,3 +379,11 @@ name_already_exists_in_module=同层级下已经存在
rerun_warning=当前报告正在重跑中
report_warning=报告类型和报告ID不能为空
report_type_error=报告类型错误
#ui 元素库
ui_element_name=元素名称
ui_element_locator=元素定位
ui_element_locator_type=定位类型
ui_element_import_template_name=元素库导入模板
ui_element_import_template_sheet=模板
ui_element_already_exists_excel=文件中存在多条相同数据
ui_element_already_exists_data=已经存在同名元素

View File

@ -378,3 +378,11 @@ name_already_exists_in_module=同層級下已存在
rerun_warning=當前報告正在重跑中
report_warning=報告類型和報告ID不能為空
report_type_error=報告類型錯誤
#ui 元素库
ui_element_name=元素名稱
ui_element_locator=元素定位
ui_element_locator_type=定位類型
ui_element_import_template_name=元素庫導入模板
ui_element_import_template_sheet=模板
ui_element_already_exists_excel=文件中存在多條相同數據
ui_element_already_exists_data=已經存在同名元素

View File

@ -145,6 +145,12 @@ export default {
return false;
}
},
showRemoveTip: {
type: Boolean,
default() {
return true;
}
},
updatePermission: Array,
addPermission: Array,
deletePermission: Array,
@ -349,17 +355,24 @@ export default {
}
let tip = '确定删除节点 ' + data.label + ' 及其子节点下所有资源' + '';
// let info = this.$t("test_track.module.delete_confirm") + data.label + "" + this.$t("test_track.module.delete_all_resource") + "";
if(this.showRemoveTip){
this.$alert(tip, "", {
confirmButtonText: this.$t("commons.confirm"),
callback: action => {
if (action === "confirm") {
let nodeIds = [];
this.getChildNodeId(node.data, nodeIds);
this.$emit('remove', nodeIds);
this.$emit('remove', nodeIds, data);
}
}
}
);
}else {
let nodeIds = [];
this.getChildNodeId(node.data, nodeIds);
this.$emit('remove', nodeIds, data);
}
},
handleDragEnd(draggingNode, dropNode, dropType, ev) {
if (dropType === "none" || dropType === undefined) {

@ -1 +1 @@
Subproject commit 218a3cadaf6715d318e8cd4a4b3f6502070a5453
Subproject commit 9b9233d775b00461cc29a537243ff391fe0bf2e8

View File

@ -270,7 +270,8 @@ export let CUSTOM_TABLE_HEADER = {
{id: 'location', key: '4', label: '元素定位'},
{id: 'createUser', key: '5', label: '创建人'},
{id: 'createTime', key: '6', label: 'commons.create_time'},
{id: 'updateTime', key: '7', label: 'commons.update_time'},
{id: 'updateUser', key: '7', label: '更新人'},
{id: 'updateTime', key: '8', label: 'commons.update_time'},
],
//空间配额