ui自动化报表截图查看
This commit is contained in:
@@ -1,5 +1,9 @@
|
||||
package com.test.test.controller;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.List;
|
||||
|
||||
import com.test.test.domain.UiReport;
|
||||
@@ -7,14 +11,7 @@ import com.test.test.service.IUiReportService;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import com.test.common.annotation.Log;
|
||||
import com.test.common.core.controller.BaseController;
|
||||
import com.test.common.core.domain.AjaxResult;
|
||||
@@ -70,4 +67,28 @@ public class UiReportController extends BaseController
|
||||
{
|
||||
return toAjax(uiReportService.deleteUiReportByIds(ids));
|
||||
}
|
||||
|
||||
|
||||
@GetMapping("/screenshot")
|
||||
public void getScreenshot(@RequestParam String path, HttpServletResponse response) throws IOException {
|
||||
File file = new File(path);
|
||||
if (!file.exists()) {
|
||||
try {
|
||||
response.sendError(HttpServletResponse.SC_NOT_FOUND);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
response.setContentType("image/png");
|
||||
try (FileInputStream in = new FileInputStream(file);
|
||||
OutputStream out = response.getOutputStream()) {
|
||||
byte[] buffer = new byte[4096];
|
||||
int length;
|
||||
while ((length = in.read(buffer)) > 0) {
|
||||
out.write(buffer, 0, length);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -424,13 +424,14 @@ public class UiSceneStepsServiceImpl implements IUiSceneStepsService {
|
||||
Thread.sleep(beforeAwaitTime);
|
||||
}
|
||||
|
||||
|
||||
// 3. 执行具体步骤
|
||||
stepExecution.execute(step, seleniumUtils);
|
||||
|
||||
if (screenshotConfiguration == 1) {
|
||||
report.setScreenshot(seleniumUtils.takeScreenshotAsFile(TestConfig.getProfile()));
|
||||
log.info("截图成功,路径:{}", seleniumUtils.takeScreenshotAsFile(TestConfig.getProfile()));
|
||||
}
|
||||
// 3. 执行具体步骤
|
||||
stepExecution.execute(step, seleniumUtils);
|
||||
|
||||
// 执行后置等待
|
||||
if (afterAwaitTime > 0) {
|
||||
log.info("执行后置等待: {}ms", afterAwaitTime);
|
||||
|
||||
@@ -24,3 +24,13 @@ export function getTestReportDetail(query) {
|
||||
method: 'get',
|
||||
})
|
||||
}
|
||||
|
||||
// 测试报告 - 获取截图
|
||||
export function getScreenshot(path) {
|
||||
return request({
|
||||
url: '/test/report/screenshot',
|
||||
method: 'get',
|
||||
params: { path },
|
||||
responseType: 'blob'
|
||||
})
|
||||
}
|
||||
|
||||
@@ -105,7 +105,7 @@
|
||||
</div>
|
||||
<div class="right-collapse">
|
||||
<div>{{ item.take }}</div>
|
||||
<el-button size="mini" type="text" @click.native.stop="clickHandleScreenshot">截图</el-button>
|
||||
<el-button v-if="item.screenshot" size="mini" type="text" @click.native.stop="clickHandleScreenshot(item.screenshot)">截图</el-button>
|
||||
<div class="collapse-status">
|
||||
<div v-if="item.executionFlag === '1'">成功</div>
|
||||
<div v-if="item.executionFlag === '0'">未执行</div>
|
||||
@@ -148,7 +148,7 @@
|
||||
</div>
|
||||
<div class="right-collapse">
|
||||
<div>{{ item.take }}</div>
|
||||
<el-button size="mini" type="text" @click.native.stop="clickHandleScreenshot">截图</el-button>
|
||||
<el-button v-if="item.screenshot" size="mini" type="text" @click.native.stop="clickHandleScreenshot(item.screenshot)">截图</el-button>
|
||||
<div class="collapse-status">
|
||||
<div v-if="item.executionFlag === '1'">成功</div>
|
||||
<div v-if="item.executionFlag === '0'">未执行</div>
|
||||
@@ -191,7 +191,7 @@
|
||||
</div>
|
||||
<div class="right-collapse">
|
||||
<div>{{ item.take }}</div>
|
||||
<el-button size="mini" type="text" @click.native.stop="clickHandleScreenshot">截图</el-button>
|
||||
<el-button v-if="item.screenshot" size="mini" type="text" @click.native.stop="clickHandleScreenshot(item.screenshot)">截图</el-button>
|
||||
<div class="collapse-status">
|
||||
<div v-if="item.executionFlag === '1'">成功</div>
|
||||
<div v-if="item.executionFlag === '0'">未执行</div>
|
||||
@@ -219,12 +219,25 @@
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
|
||||
<!-- 图片预览对话框 -->
|
||||
<el-dialog :visible.sync="dialogVisible" append-to-body width="80%" :close-on-click-modal="false">
|
||||
<div v-loading="imageLoading" style="min-height: 200px;">
|
||||
<el-image
|
||||
v-if="previewUrl"
|
||||
style="width: 100%"
|
||||
:src="previewUrl"
|
||||
:preview-src-list="[previewUrl]"
|
||||
fit="contain"
|
||||
/>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as echarts from 'echarts';
|
||||
import { getTestReportDetail } from '../../../api/uiTest/testReport';
|
||||
import { getTestReportDetail, getScreenshot } from '../../../api/uiTest/testReport';
|
||||
|
||||
export default {
|
||||
name: "TestReportDetail",
|
||||
@@ -233,10 +246,13 @@ export default {
|
||||
return {
|
||||
activeName: 'first',
|
||||
uiSceneStepsAllReportVOList: [], // 全部
|
||||
uiSceneStepsErrorReportVOList: [{ title: 'aaa', contentList: [{}, {}] }, { title: 'bbb', contentList: [{}, {}] }], // 失败
|
||||
uiSceneStepsNotReportVOList: [{ title: 'aaa', contentList: [{}, {}] }, { title: 'bbb', contentList: [{}, {}] }], // 未执行
|
||||
uiSceneStepsErrorReportVOList: [], // 失败
|
||||
uiSceneStepsNotReportVOList: [], // 未执行
|
||||
active: 'first',
|
||||
detailData: {}, // 详情内容
|
||||
dialogVisible: false, // 图片预览对话框是否显示
|
||||
previewUrl: '', // 预览图片的URL
|
||||
imageLoading: false, // 图片加载状态
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
@@ -255,18 +271,40 @@ export default {
|
||||
}
|
||||
})
|
||||
},
|
||||
// 截图
|
||||
clickHandleScreenshot() {
|
||||
console.log('截图')
|
||||
// 截图预览
|
||||
async clickHandleScreenshot(screenshot) {
|
||||
if (screenshot) {
|
||||
try {
|
||||
this.imageLoading = true;
|
||||
this.dialogVisible = true;
|
||||
|
||||
// 获取图片数据
|
||||
const response = await getScreenshot(screenshot);
|
||||
|
||||
// 创建 Blob URL
|
||||
const blob = new Blob([response], { type: 'image/png' });
|
||||
if (this.previewUrl) {
|
||||
URL.revokeObjectURL(this.previewUrl); // 释放之前的 URL
|
||||
}
|
||||
this.previewUrl = URL.createObjectURL(blob);
|
||||
} catch (error) {
|
||||
this.$message.error('图片加载失败');
|
||||
this.dialogVisible = false;
|
||||
} finally {
|
||||
this.imageLoading = false;
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
beforeDestroy() {
|
||||
// 清理 Blob URL
|
||||
if (this.previewUrl) {
|
||||
URL.revokeObjectURL(this.previewUrl);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
<style scoped lang="scss">
|
||||
.report-detail {
|
||||
padding: 20px;
|
||||
|
||||
Reference in New Issue
Block a user