InterfaceTest.vue 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937
  1. <template>
  2. <el-tabs class="tabs" v-model="activeTab">
  3. <el-tab-pane label="接口测试" name="interfaceTest">
  4. <el-table :data="interfaceTests" style="width: 100%" height="600">
  5. <el-table-column type="expand">
  6. <template #default="props">
  7. <el-row type="flex" justify="center">
  8. <el-col :span="24">
  9. <el-row class="entry-row">
  10. <el-col :span="2">
  11. <h4>待测url:</h4>
  12. </el-col>
  13. <el-col :span="18">
  14. <div>{{props.row.url}}</div>
  15. </el-col>
  16. </el-row>
  17. <el-row class="entry-row">
  18. <el-col :span="2">
  19. <h4>测试方法:</h4>
  20. </el-col>
  21. <el-col :span="18">
  22. <el-tag :type="props.row.method === 'GET' ? 'success' : ''">{{props.row.method}}</el-tag>
  23. </el-col>
  24. </el-row>
  25. <el-row class="entry-row">
  26. <el-col :span="2">
  27. <h4 v-if="props.row.method === 'GET'">url携带参数:</h4>
  28. <h4 v-else>请求体:</h4>
  29. </el-col>
  30. <el-col :span="8">
  31. <el-input :value="strToJSON(props.row.params)" type="textarea" :rows="4" disabled></el-input>
  32. </el-col>
  33. </el-row>
  34. </el-col>
  35. </el-row>
  36. </template>
  37. </el-table-column>
  38. <el-table-column
  39. prop="id"
  40. label="ID"
  41. width="60"
  42. align="center">
  43. </el-table-column>
  44. <el-table-column
  45. prop="name"
  46. label="测试名称"
  47. width="300"
  48. align="center">
  49. </el-table-column>
  50. <el-table-column
  51. prop="username"
  52. label="创建者"
  53. align="center"
  54. width="170">
  55. </el-table-column>
  56. <el-table-column
  57. prop="createTime"
  58. label="创建时间"
  59. align="center"
  60. width="170">
  61. </el-table-column>
  62. <el-table-column
  63. label="详情"
  64. align="center">
  65. <template #default="scope">
  66. <el-button
  67. @click="handleClick('detail', scope.row.id)"
  68. type="text"
  69. size="small">查看详情</el-button>
  70. </template>
  71. </el-table-column>
  72. <el-table-column
  73. align="center">
  74. <template #header>
  75. <span>操作</span>
  76. <el-button @click="handleClick('create')" type="text" class="add-button">新建</el-button>
  77. </template>
  78. <template #default="scope">
  79. <el-button @click="handleClick('trigger', scope.row.id)" type="text" size="small">触发</el-button>
  80. <el-button @click="handleClick('delete', scope.row.id)" type="text" size="small">删除</el-button>
  81. </template>
  82. </el-table-column>
  83. </el-table>
  84. </el-tab-pane>
  85. <el-tab-pane label="黑盒测试" name="funcTest">
  86. <el-table :data="testcases" width="100%">
  87. <el-table-column
  88. prop="id"
  89. label="ID"
  90. align="center"
  91. width="60"></el-table-column>
  92. <el-table-column
  93. prop="title"
  94. label="标题"
  95. align="center">
  96. </el-table-column>
  97. <el-table-column
  98. prop="taskId"
  99. label="关联的任务ID"
  100. align="center"
  101. width="150">
  102. </el-table-column>
  103. <el-table-column
  104. prop="pass"
  105. label="执行状态"
  106. align="center"
  107. width="100"
  108. :filters="[{ text: '进行中', value: false }, { text: '已完成', value: true }]"
  109. :filter-method="(value, row) => {
  110. return row.pass === value;
  111. }"
  112. filter-placement="bottom-end">
  113. <template #default="scope">
  114. <template v-if="scope.row.pass === false">
  115. <el-tag>进行中<i class="el-icon-loading"></i></el-tag>
  116. </template>
  117. <template v-else-if="scope.row.pass === true">
  118. <el-tag type="success">已完成</el-tag>
  119. </template>
  120. <template v-else>
  121. <el-tag type="warning">未知状态</el-tag>
  122. </template>
  123. </template>
  124. </el-table-column>
  125. <el-table-column
  126. label="详情"
  127. align="center"
  128. width="120">
  129. <template #default="scope">
  130. <el-button
  131. @click="handleTestCasesClick('steps', scope.row.id)"
  132. type="text"
  133. size="small">测试用例步骤列表</el-button>
  134. </template>
  135. </el-table-column>
  136. <el-table-column
  137. align="center">
  138. <template #header>
  139. <span>操作</span>
  140. <el-button
  141. @click="handleTestCasesClick('latest', 0)"
  142. type="text"
  143. class="add-button">部署的历史记录</el-button>
  144. <el-button @click="handleTestCasesClick('create')" type="text" class="add-button">新建</el-button>
  145. </template>
  146. <template #default="scope">
  147. <el-button v-if="scope.row.pass === false" @click="handleTestCasesClick('finish', scope.row.id)" type="text" size="small">
  148. 完成测试
  149. </el-button>
  150. <el-button v-else @click="handleTestCasesClick('finish', scope.row.id)" type="text" size="small" disabled>完成测试</el-button>
  151. <el-button v-if="scope.row.pass === true" @click="handleTestCasesClick('reopen', scope.row.id)" type="text" size="small">
  152. 重新开放测试
  153. </el-button>
  154. <el-button v-else @click="handleTestCasesClick('reopen', scope.row.id)" type="text" size="small" disabled>重新开放测试</el-button>
  155. <el-button @click="handleTestCasesClick('edit', scope.row.id)" type="text" size="small">编辑</el-button>
  156. <el-button @click="handleTestCasesClick('delete', scope.row.id)" type="text" size="small">删除</el-button>
  157. </template>
  158. </el-table-column>
  159. </el-table>
  160. </el-tab-pane>
  161. </el-tabs>
  162. <el-dialog
  163. v-model="createInterfaceDialog"
  164. width="600px"
  165. :before-close="(done) => {$refs['createInterfaceTestForm'].resetFields();done();}"
  166. destroy-on-close>
  167. <template #title>创建接口测试</template>
  168. <el-form
  169. :model="createInterfaceTestForm"
  170. ref="createInterfaceTestForm"
  171. label-position="right"
  172. label-width="100px"
  173. label-suffix=":"
  174. style="width: 80%; margin: 0 auto;">
  175. <el-form-item label="测试名称" prop="name" required>
  176. <el-input v-model="createInterfaceTestForm.name" placeholder="请输入接口测试的名称"></el-input>
  177. </el-form-item>
  178. <el-form-item label="待测URL" prop="url" required>
  179. <el-input v-model="createInterfaceTestForm.url" placeholder="请输入待测试的URL"></el-input>
  180. </el-form-item>
  181. <el-form-item label="方法" prop="method" required>
  182. <el-select v-model="createInterfaceTestForm.method" placeholder="请选择待测URL的方法">
  183. <el-option
  184. v-for="(method, index) in methodList"
  185. :key="index"
  186. :value="method">
  187. </el-option>
  188. </el-select>
  189. </el-form-item>
  190. <el-form-item :label="createInterfaceTestForm.method === 'POST' ? '请求体' : '携带参数'" prop="params">
  191. <div>
  192. <vue-json-editor
  193. :height="'400px'"
  194. v-model="createInterfaceTestForm.params"
  195. :show-btns="false"
  196. mode="code"
  197. :modes="['code']"
  198. lang="zh"
  199. @json-change="onJsonChange"
  200. @json-save="onJsonSave"
  201. ></vue-json-editor>
  202. </div>
  203. </el-form-item>
  204. </el-form>
  205. <template #footer>
  206. <span class="dialog-footer">
  207. <el-button type="primary" @click="handleInterfaceCreateConfirm()">确 定</el-button>
  208. </span>
  209. </template>
  210. </el-dialog>
  211. <el-drawer
  212. v-model="detailDrawer"
  213. :size="650">
  214. <template #title>
  215. <el-row class="entry-row">
  216. <el-col :span="2">
  217. <div class="node-type">测试</div>
  218. </el-col>
  219. <el-col :span="2">
  220. <template class="entry-row">
  221. <span>#{{detailInterfaceTestInfo.id}}</span>
  222. </template>
  223. </el-col>
  224. <el-col :span="20">
  225. <template class="entry-row">
  226. <span>{{detailInterfaceTestInfo.name}}</span>
  227. </template>
  228. </el-col>
  229. </el-row>
  230. </template>
  231. <template #default>
  232. <el-divider content-position="left">测试任务信息</el-divider>
  233. <div style="width: 80%; margin: 0 auto">
  234. <el-row type="flex" align="center">
  235. <el-col :span="24">
  236. <el-row class="entry-row">
  237. <el-col :span="6">
  238. <h4>待测url:</h4>
  239. </el-col>
  240. <el-col :span="18">
  241. <div>{{detailInterfaceTestInfo.url}}</div>
  242. </el-col>
  243. </el-row>
  244. <el-row class="entry-row">
  245. <el-col :span="6">
  246. <h4>测试方法:</h4>
  247. </el-col>
  248. <el-col :span="18">
  249. <el-tag :type="detailInterfaceTestInfo.method === 'GET' ? 'success' : ''">{{detailInterfaceTestInfo.method}}</el-tag>
  250. </el-col>
  251. </el-row>
  252. <el-row class="entry-row">
  253. <el-col :span="6">
  254. <h4 v-if="detailInterfaceTestInfo.method === 'GET'">url携带参数:</h4>
  255. <h4 v-else>请求体:</h4>
  256. </el-col>
  257. <el-col :span="18">
  258. <el-input :value="strToJSON(detailInterfaceTestInfo.params)" type="textarea" :rows="4" disabled></el-input>
  259. </el-col>
  260. </el-row>
  261. </el-col>
  262. </el-row>
  263. </div>
  264. <el-divider content-position="left">测试执行结果</el-divider>
  265. <div style="width: 95%; margin: 0 auto">
  266. <el-tabs v-model="activeTab1">
  267. <el-tab-pane label="手动触发结果" name="artificial">
  268. <el-table :data="interfaceTestResults" style="width: 100%" height="800" border>
  269. <el-table-column type="expand">
  270. <template #default="props">
  271. <el-row type="flex" justify="center">
  272. <el-col :span="24">
  273. <el-row class="entry-row">
  274. <el-col :span="4">
  275. <h4>返回结果:</h4>
  276. </el-col>
  277. <el-col :span="20">
  278. <el-input :value="strToJSON(props.row.result)" type="textarea" :rows="8" disabled></el-input>
  279. </el-col>
  280. </el-row>
  281. </el-col>
  282. </el-row>
  283. </template>
  284. </el-table-column>
  285. <el-table-column
  286. prop="id"
  287. label="ID"
  288. width="40"
  289. align="center">
  290. </el-table-column>
  291. <el-table-column
  292. prop="executeTime"
  293. label="执行时间"
  294. width="170"
  295. align="center">
  296. </el-table-column>
  297. <el-table-column
  298. prop="username"
  299. label="执行者"
  300. width="100"
  301. align="center">
  302. </el-table-column>
  303. <el-table-column
  304. prop="code"
  305. label="状态码"
  306. width="80"
  307. align="center">
  308. <template #default="scope">
  309. <el-tag disable-transitions>{{scope.row.code}}</el-tag>
  310. </template>
  311. </el-table-column>
  312. <el-table-column
  313. prop="cost"
  314. label="耗时/ms"
  315. align="center">
  316. </el-table-column>
  317. </el-table>
  318. </el-tab-pane>
  319. <el-tab-pane label="自动化测试结果">
  320. <el-table :data="interfaceTestAutoResults" style="width: 100%" height="800" border>
  321. <el-table-column type="expand">
  322. <template #default="props">
  323. <el-row type="flex" justify="center">
  324. <el-col :span="24">
  325. <el-row class="entry-row">
  326. <el-col :span="4">
  327. <h4>返回结果:</h4>
  328. </el-col>
  329. <el-col :span="20">
  330. <el-input :value="strToJSON(props.row.result)" type="textarea" :rows="8" disabled></el-input>
  331. </el-col>
  332. </el-row>
  333. </el-col>
  334. </el-row>
  335. </template>
  336. </el-table-column>
  337. <el-table-column
  338. prop="id"
  339. label="ID"
  340. width="40"
  341. align="center">
  342. </el-table-column>
  343. <el-table-column
  344. prop="deploymentId"
  345. label="流水线ID"
  346. width="100"
  347. align="center">
  348. </el-table-column>
  349. <el-table-column
  350. prop="executeTime"
  351. label="执行时间"
  352. width="170"
  353. align="center">
  354. </el-table-column>
  355. <el-table-column
  356. prop="username"
  357. label="执行者"
  358. width="100"
  359. align="center">
  360. </el-table-column>
  361. <el-table-column
  362. prop="code"
  363. label="状态码"
  364. width="80"
  365. align="center">
  366. <template #default="scope">
  367. <el-tag disable-transitions>{{scope.row.code}}</el-tag>
  368. </template>
  369. </el-table-column>
  370. <el-table-column
  371. prop="cost"
  372. label="耗时/ms"
  373. align="center">
  374. </el-table-column>
  375. </el-table>
  376. </el-tab-pane>
  377. </el-tabs>
  378. </div>
  379. </template>
  380. </el-drawer>
  381. <!-- 部署的历史记录 -->
  382. <ElDrawer
  383. v-model="deployHistoryDrawer"
  384. :size="650">
  385. <template #title>
  386. <el-row class="entry-row">
  387. <el-col :span="3">
  388. <div class="node-type">项目</div>
  389. </el-col>
  390. <el-col :span="2">
  391. <template class="entry-row">
  392. <span>#{{currentProjectId}}</span>
  393. </template>
  394. </el-col>
  395. </el-row>
  396. </template>
  397. <template #default>
  398. <el-row type="flex" justify="center">
  399. <el-col :span="20">
  400. <el-table :data="deployHistoryInfo" width="100%">
  401. <el-table-column
  402. prop="id"
  403. label="ID"
  404. align="center"
  405. width="60">
  406. </el-table-column>
  407. <el-table-column
  408. prop="timestamp"
  409. label="部署时间"
  410. align="center"
  411. width="150">
  412. </el-table-column>
  413. <el-table-column
  414. prop="operationType"
  415. label="操作类型"
  416. align="center">
  417. </el-table-column>
  418. <el-table-column
  419. prop="pipelineRecordId"
  420. label="流水线ID"
  421. align="center"
  422. width="80">
  423. </el-table-column>
  424. </el-table>
  425. </el-col>
  426. </el-row>
  427. </template>
  428. </ElDrawer>
  429. <!-- 新建测试用例 -->
  430. <el-dialog
  431. v-model="showTestCaseCreateModel"
  432. width="600px"
  433. :before-close="(done) => {$refs['createTestCaseForm'].resetFields();done();}"
  434. destroy-on-close>
  435. <template #title>创建测试用例</template>
  436. <el-form
  437. :model="createTestCaseForm"
  438. ref="createTestCaseForm"
  439. label-position="right"
  440. label-width="70px"
  441. label-suffix=":"
  442. class="create-APITest-form">
  443. <el-form-item label="title" prop="title">
  444. <el-input
  445. v-model="createTestCaseForm.title"
  446. type="textarea"
  447. :rows="5"
  448. placeholder="请输入测试用例的标题"></el-input>
  449. </el-form-item>
  450. <el-form-item label="taskId" prop="taskId">
  451. <el-select v-model="createTestCaseForm.taskId">
  452. <el-option
  453. v-for="item in taskIdList"
  454. :key="item"
  455. :value="item"></el-option>
  456. </el-select>
  457. </el-form-item>
  458. </el-form>
  459. <template #footer>
  460. <span class="dialog-footer">
  461. <el-button type="primary" @click="handleTestCaseCreateConfirm">确 定</el-button>
  462. </span>
  463. </template>
  464. </el-dialog>
  465. <!-- 测试用例步骤详情 -->
  466. <el-drawer
  467. v-model="stepsDrawer"
  468. :size="700">
  469. <template #title>
  470. <el-row class="entry-row">
  471. <el-col :span="3">
  472. <div class="node-type">测试用例</div>
  473. </el-col>
  474. <el-col :span="2">
  475. <template class="entry-row">
  476. <span>#{{detailTestCaseInfo.id}}</span>
  477. </template>
  478. </el-col>
  479. <el-col :span="8">
  480. <template class="entry-row">
  481. <span>{{detailTestCaseInfo.title}}</span>
  482. </template>
  483. </el-col>
  484. </el-row>
  485. </template>
  486. <template #default>
  487. <el-divider content-position="left">新建测试用例步骤</el-divider>
  488. <div style="width: 90%; margin: 0 auto;">
  489. <el-button @click="handleSteps('create', detailTestCaseInfo.id, 0)" type="text" class="add-button">新建测试用例步骤</el-button>
  490. </div>
  491. <el-divider content-position="left">测试用例步骤</el-divider>
  492. <div style="width: 95%; margin: 0 auto;">
  493. <el-row type="flex" justify="center">
  494. <el-col :span="24">
  495. <el-table :data="detailStepsInfo" width="100%">
  496. <el-table-column
  497. prop="id"
  498. label="ID"
  499. align="center"
  500. width="60">
  501. </el-table-column>
  502. <el-table-column
  503. prop="description"
  504. label="描述"
  505. align="center">
  506. </el-table-column>
  507. <el-table-column
  508. prop="expectation"
  509. label="预期输出"
  510. align="center">
  511. </el-table-column>
  512. <el-table-column
  513. prop="state"
  514. label="状态"
  515. align="center">
  516. </el-table-column>
  517. <el-table-column
  518. align="center">
  519. <template #header>
  520. <span>操作</span>
  521. </template>
  522. <template #default="scope">
  523. <el-button @click="handleSteps('update', scope.row.testCaseId, scope.row.id)" type="text" size="small">更新</el-button>
  524. <el-button
  525. @click="handleSteps('updateState', scope.row.testCaseId, scope.row.id)" type="text" size="small">修改状态</el-button>
  526. <el-button @click="handleSteps('delete', scope.row.testCaseId, scope.row.id)" type="text" size="small">删除</el-button>
  527. </template>
  528. </el-table-column>
  529. </el-table>
  530. </el-col>
  531. </el-row>
  532. </div>
  533. </template>
  534. </el-drawer>
  535. <!-- 修改测试用例步骤 -->
  536. <el-dialog
  537. v-model="showUpdateStepModel"
  538. width="600px"
  539. :before-close="(done) => {$refs['updateStepForm'].resetFields();done();}"
  540. destroy-on-close>
  541. <template #title>修改测试用例步骤</template>
  542. <el-form
  543. :model="updateStepForm"
  544. ref="updateStepForm"
  545. label-position="right"
  546. label-width="100px"
  547. label-suffix=":">
  548. <el-form-item label="id" prop="id">
  549. <el-input
  550. v-model="updateStepForm.id"
  551. disabled>
  552. </el-input>
  553. </el-form-item>
  554. <el-form-item label="description" prop="description">
  555. <el-input
  556. v-model="updateStepForm.description"
  557. type="textarea"
  558. :rows="4">
  559. </el-input>
  560. </el-form-item>
  561. <el-form-item label="expectation" prop="expectation">
  562. <el-input
  563. v-model="updateStepForm.expectation"
  564. type="textarea"
  565. :rows="4">
  566. </el-input>
  567. </el-form-item>
  568. </el-form>
  569. <template #footer>
  570. <span class="dialog-footer">
  571. <el-button type="primary" @click="handleStepUpdateConfirm">确 定</el-button>
  572. </span>
  573. </template>
  574. </el-dialog>
  575. <!-- 修改测试用例步骤state -->
  576. <el-dialog
  577. v-model="showUpdateStepStateModel"
  578. width="600px"
  579. :before-close="(done) => {$refs['updateStepForm'].resetFields();done();}"
  580. destroy-on-close>
  581. <template #title>修改测试用例步骤状态</template>
  582. <el-form
  583. :model="updateStepForm"
  584. ref="updateStepForm"
  585. label-position="right"
  586. label-width="100px"
  587. label-suffix=":">
  588. <el-form-item label="id" prop="id">
  589. <el-input
  590. v-model="updateStepForm.id"
  591. disabled>
  592. </el-input>
  593. </el-form-item>
  594. <el-form-item label="state" prop="state">
  595. <el-select
  596. v-model="updateStepForm.state">
  597. <el-option
  598. v-for="(state, index) in stateList"
  599. :key="index"
  600. :label="state"
  601. :value="state">
  602. </el-option>
  603. </el-select>
  604. </el-form-item>
  605. </el-form>
  606. <template #footer>
  607. <span class="dialog-footer">
  608. <el-button type="primary" @click="handleStepUpdateStateConfirm">确 定</el-button>
  609. </span>
  610. </template>
  611. </el-dialog>
  612. <!-- 修改测试用例title -->
  613. <el-dialog
  614. v-model="showEditTestCaseModel"
  615. width="600px"
  616. :before-close="(done) => {$refs['detailTestCaseInfo'].resetFields();done();}"
  617. destroy-on-close>
  618. <template #title>编辑测试用例标题</template>
  619. <el-form
  620. :model="detailTestCaseInfo"
  621. ref="detailTestCaseInfo"
  622. label-position="right"
  623. label-width="100px"
  624. label-suffix=":">
  625. <el-form-item label="id" prop="id">
  626. <el-input
  627. v-model="detailTestCaseInfo.id"
  628. disabled>
  629. </el-input>
  630. </el-form-item>
  631. <el-form-item label="title" prop="title">
  632. <el-input
  633. v-model="detailTestCaseInfo.title"
  634. type="textarea"
  635. :rows="4">
  636. </el-input>
  637. </el-form-item>
  638. </el-form>
  639. <template #footer>
  640. <span class="dialog-footer">
  641. <el-button type="primary" @click="handleTestCaseEditConfirm">确 定</el-button>
  642. </span>
  643. </template>
  644. </el-dialog>
  645. </template>
  646. <script>
  647. import vueJsonEditor from 'vue-json-editor';
  648. import { InterfaceTestAPI, FuncTestAPI } from '@/api';
  649. import { ElMessage } from 'element-plus';
  650. export default {
  651. components: {
  652. vueJsonEditor,
  653. },
  654. data() {
  655. return {
  656. currentProjectId: -1,
  657. activeTab: 'interfaceTest',
  658. activeTab1: 'artificial',
  659. interfaceTests: [],
  660. createInterfaceDialog: false,
  661. createInterfaceTestForm: {},
  662. methodList: ['GET', 'POST'],
  663. jsonValid: true,
  664. detailInterfaceTestInfo: {},
  665. interfaceTestResults: [],
  666. interfaceTestAutoResults: [],
  667. detailDrawer: false,
  668. testcases: [],
  669. taskIdList: [],
  670. showTestCaseCreateModel: false,
  671. deployHistoryInfo: {},
  672. deployHistoryDrawer: false,
  673. detailTestCaseInfo: {},
  674. showEditTestCaseModel: false,
  675. detailStepsInfo: {},
  676. stepsDrawer: false,
  677. showUpdateStepModel: false,
  678. updateStepForm: {},
  679. showUpdateStepStateModel: false,
  680. createTestCaseForm: {},
  681. stateList: ['待测试', '已测试', '出现bug'],
  682. };
  683. },
  684. async mounted() {
  685. this.currentProjectId = this.$store.state.workspace.currentProjectId;
  686. this.interfaceTests = await InterfaceTestAPI.getAll(this.currentProjectId);
  687. this.testcases = await FuncTestAPI.getTestCases(this.currentProjectId);
  688. this.taskIdList = await FuncTestAPI.getTreeIdList(this.currentProjectId);
  689. },
  690. methods: {
  691. strToJSON(params) {
  692. return JSON.stringify(params, null, 4);
  693. },
  694. async handleClick(action, id) {
  695. switch (action) {
  696. case 'create': {
  697. this.createInterfaceDialog = true;
  698. break;
  699. }
  700. case 'delete': {
  701. await InterfaceTestAPI.deleteTest(id);
  702. ElMessage.success('删除成功!');
  703. this.interfaceTests = await InterfaceTestAPI.getAll(this.currentProjectId);
  704. break;
  705. }
  706. case 'trigger': {
  707. await InterfaceTestAPI.executeTest(id, this.$store.state.user.username, 'artificial');
  708. this.timer = setTimeout(() => {
  709. this.$nextTick(() => {
  710. ElMessage.success('执行成功!');
  711. });
  712. }, 3000);
  713. break;
  714. }
  715. case 'detail': {
  716. this.interfaceTests.forEach((item) => {
  717. if (item.id === id) {
  718. this.detailInterfaceTestInfo = item;
  719. }
  720. });
  721. this.interfaceTestResults = await InterfaceTestAPI.getResults(id);
  722. this.interfaceTestAutoResults = await InterfaceTestAPI.getAutoResults(id);
  723. this.interfaceTestResults.forEach((item) => {
  724. item.result = JSON.parse(item.result);
  725. });
  726. this.interfaceTestAutoResults.forEach((item) => {
  727. item.result = JSON.parse(item.result);
  728. });
  729. this.detailDrawer = true;
  730. break;
  731. }
  732. default: {
  733. console.log('Unknown type of action.');
  734. }
  735. }
  736. },
  737. onJsonChange(value) {
  738. this.onJsonSave(value);
  739. },
  740. onJsonSave(value) {
  741. this.createInterfaceTestForm.params = value;
  742. },
  743. async handleInterfaceCreateConfirm() {
  744. this.$refs.createInterfaceTestForm.validate(async (valid) => {
  745. if (valid) {
  746. await InterfaceTestAPI.createTest({
  747. projectId: this.currentProjectId,
  748. createTime: '',
  749. username: this.$store.state.user.username,
  750. name: this.createInterfaceTestForm.name,
  751. url: this.createInterfaceTestForm.url,
  752. method: this.createInterfaceTestForm.method,
  753. params: this.createInterfaceTestForm.params,
  754. });
  755. this.interfaceTests = await InterfaceTestAPI.getAll(this.currentProjectId);
  756. this.$refs.createInterfaceTestForm.resetFields();
  757. this.createInterfaceDialog = false;
  758. ElMessage.success('创建成功!');
  759. }
  760. });
  761. },
  762. async handleTestCasesClick(action, id) {
  763. switch (action) {
  764. case 'create': {
  765. this.showTestCaseCreateModel = true;
  766. break;
  767. }
  768. case 'latest': {
  769. this.deployHistoryInfo = await FuncTestAPI.getLatestRecord(this.$store.state.workspace.currentProjectId);
  770. this.deployHistoryDrawer = true;
  771. break;
  772. }
  773. case 'finish': {
  774. await FuncTestAPI.finishTestCase(id);
  775. this.testcases = await FuncTestAPI.getTestCases(this.$store.state.workspace.currentProjectId);
  776. break;
  777. }
  778. case 'reopen': {
  779. await FuncTestAPI.reopenTestCase(id);
  780. this.testcases = await FuncTestAPI.getTestCases(this.$store.state.workspace.currentProjectId);
  781. break;
  782. }
  783. case 'edit': {
  784. this.testcases.forEach((item) => {
  785. if (item.id === id) {
  786. this.detailTestCaseInfo = item;
  787. }
  788. });
  789. this.showEditTestCaseModel = true;
  790. break;
  791. }
  792. case 'delete': {
  793. await FuncTestAPI.deleteTestCase(id);
  794. ElMessage.success('删除成功!');
  795. this.testcases = await FuncTestAPI.getTestCases(this.$store.state.workspace.currentProjectId);
  796. break;
  797. }
  798. case 'steps': {
  799. this.testcases.forEach((item) => {
  800. if (item.id === id) {
  801. this.detailTestCaseInfo = item;
  802. }
  803. });
  804. this.detailStepsInfo = await FuncTestAPI.getTestCaseSteps(id);
  805. this.stepsDrawer = true;
  806. break;
  807. }
  808. default: {
  809. console.warn('Unknown type of action.');
  810. }
  811. }
  812. },
  813. async handleTestCaseCreateConfirm() {
  814. this.$refs.createTestCaseForm.validate(async (valid) => {
  815. if (valid) {
  816. this.createTestCaseForm.projectId = this.$store.state.workspace.currentProjectId;
  817. await FuncTestAPI.createTestCase(
  818. this.createTestCaseForm.projectId, this.createTestCaseForm.title, this.createTestCaseForm.taskId,
  819. );
  820. this.testcases = await FuncTestAPI.getTestCases(this.$store.state.workspace.currentProjectId);
  821. this.$refs.createTestCaseForm.resetFields();
  822. this.showTestCaseCreateModel = false;
  823. ElMessage.success('创建成功!');
  824. }
  825. });
  826. },
  827. async handleSteps(action, caseId, stepId) {
  828. switch (action) {
  829. case 'create': {
  830. await FuncTestAPI.createTestCaseStep(caseId);
  831. this.detailStepsInfo = await FuncTestAPI.getTestCaseSteps(caseId);
  832. ElMessage.success('创建成功!');
  833. break;
  834. }
  835. case 'delete': {
  836. await FuncTestAPI.deleteTestCaseStep(stepId);
  837. ElMessage.success('删除成功!');
  838. this.detailStepsInfo = await FuncTestAPI.getTestCaseSteps(caseId);
  839. break;
  840. }
  841. case 'update': {
  842. this.showUpdateStepModel = true;
  843. this.detailStepsInfo.forEach((item) => {
  844. if (item.id === stepId) {
  845. this.updateStepForm = item;
  846. }
  847. });
  848. break;
  849. }
  850. case 'updateState': {
  851. this.showUpdateStepStateModel = true;
  852. this.detailStepsInfo.forEach((item) => {
  853. if (item.id === stepId) {
  854. this.updateStepForm = item;
  855. }
  856. });
  857. break;
  858. }
  859. default: {
  860. console.warn('Unknown type of action.');
  861. }
  862. }
  863. },
  864. async handleStepUpdateConfirm() {
  865. this.$refs.updateStepForm.validate(async (valid) => {
  866. if (valid) {
  867. await FuncTestAPI.updateTestCaseStep(this.updateStepForm.id, this.updateStepForm.description, this.updateStepForm.expectation);
  868. this.detailStepsInfo = await FuncTestAPI.getTestCaseSteps(this.updateStepForm.testCaseId);
  869. this.$refs.updateStepForm.resetFields();
  870. this.showUpdateStepModel = false;
  871. ElMessage.success('修改成功!');
  872. }
  873. });
  874. },
  875. async handleStepUpdateStateConfirm() {
  876. this.$refs.updateStepForm.validate(async (valid) => {
  877. if (valid) {
  878. let state;
  879. if (this.updateStepForm.state === '待测试') {
  880. state = 'WAITING';
  881. } else if (this.updateStepForm.state === '已测试') {
  882. state = 'PASS';
  883. } else if (this.updateStepForm.state === '出现bug') {
  884. state = 'BUG';
  885. }
  886. await FuncTestAPI.updateTestCaseStepState(this.updateStepForm.id, state);
  887. this.detailStepsInfo = await FuncTestAPI.getTestCaseSteps(this.updateStepForm.testCaseId);
  888. this.$refs.updateStepForm.resetFields();
  889. this.showUpdateStepStateModel = false;
  890. ElMessage.success('修改成功!');
  891. }
  892. });
  893. },
  894. async handleTestCaseEditConfirm() {
  895. this.$refs.detailTestCaseInfo.validate(async (valid) => {
  896. if (valid) {
  897. await FuncTestAPI.updateTestCase(this.detailTestCaseInfo.id, this.detailTestCaseInfo.title);
  898. this.testcases = await FuncTestAPI.getTestCases(this.$store.state.workspace.currentProjectId);
  899. this.$refs.detailTestCaseInfo.resetFields();
  900. this.showEditTestCaseModel = false;
  901. ElMessage.success('修改成功!');
  902. }
  903. });
  904. },
  905. },
  906. };
  907. </script>
  908. <style lang="scss" scoped>
  909. .tabs {
  910. width: 80%;
  911. margin: auto auto;
  912. }
  913. .add-button {
  914. margin-left: 14px;
  915. }
  916. .entry-row {
  917. width: 100%;
  918. margin: 3px 20px;
  919. display: flex;
  920. flex-direction: row;
  921. align-items: center;
  922. justify-content: flex-start;
  923. h3, h4{
  924. color: #172b4d;
  925. }
  926. }
  927. .node-type{
  928. color: #FFFFFF;
  929. border-radius: 3px;
  930. font-size: 14px;
  931. background-color: #42b983;
  932. text-align: center;
  933. }
  934. </style>