1 <!DOCTYPE html>2 <html lang="es">3 <head>4 <meta charset="UTF-8">5 <title>Plataforma de Testing Automatizado de APIs</title>6 <!-- Enlaces a Bootstrap CSS y Bootstrap Icons -->7 <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">8 <link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.5/font/bootstrap-icons.css" rel="stylesheet">9 <!-- Estilos personalizados -->10 <style>11 body {12 background-color: var(--bs-body-bg);13 color: var(--bs-body-color);14 transition: background-color 0.3s, color 0.3s;15 }16 .card {17 margin-bottom: 20px;18 transition: transform 0.2s;19 }20 .card:hover {21 transform: translateY(-5px);22 }23 .strike-through {24 text-decoration: line-through;25 color: #999;26 }27 .add-button {28 margin-top: 10px;29 }30 .navbar-brand img {31 height: 40px;32 }33 .theme-toggle {34 cursor: pointer;35 }36 </style>37 </head>38 <body>39 <!-- Barra de navegación -->40 <nav class="navbar navbar-expand-lg navbar-dark bg-primary mb-4">41 <div class="container-fluid">42 <a class="navbar-brand" href="#">43 <!-- Logo -->44 <img src="https://via.placeholder.com/150x40?text=Logo" alt="Logo">45 </a>46 <span class="navbar-text text-white">47 Plataforma de Testing Automatizado de APIs48 </span>49 <button class="btn btn-secondary ms-auto theme-toggle" id="themeToggle">50 <i class="bi bi-moon-fill"></i>51 </button>52 </div>53 </nav>54 55 <div id="app" class="container">56 <!-- Variables -->57 <div class="card">58 <div class="card-header">59 <h5>Variables</h5>60 </div>61 <div class="card-body">62 <div class="mb-3 row">63 <label class="col-sm-2 col-form-label">Set var</label>64 <div class="col-sm-4">65 <input type="text" class="form-control" v-model="variables.name">66 </div>67 <label class="col-sm-1 col-form-label text-center">=</label>68 <div class="col-sm-5">69 <input type="text" class="form-control" v-model="variables.value">70 </div>71 </div>72 <div class="mb-3 form-check">73 <input type="checkbox" class="form-check-input" id="assertVariable" v-model="variables.assert">74 <label class="form-check-label" for="assertVariable">75 Assert {{ variables.name }} is one of76 </label>77 <input type="text" class="form-control mt-2" v-if="variables.assert" v-model="variables.assertValues" placeholder="Valores separados por coma">78 </div>79 </div>80 </div>81 82 <!-- Request -->83 <div class="card">84 <div class="card-header">85 <h5>86 REQUEST87 <select class="form-select d-inline w-auto ms-2" v-model="request.method">88 <option>GET</option>89 <option>POST</option>90 <option>PUT</option>91 <option>DELETE</option>92 </select>93 </h5>94 </div>95 <div class="card-body">96 <!-- URL -->97 <div class="mb-3">98 <label class="form-label">URL</label>99 <input type="text" class="form-control" v-model="request.url" @input="validateURL">100 <div class="invalid-feedback" v-if="!validURL">101 Por favor, introduce una URL válida.102 </div>103 </div>104 <!-- Headers -->105 <div class="mb-3">106 <label class="form-label">Headers</label>107 <div v-for="(header, index) in request.headers" :key="index" class="row g-2 mb-2 align-items-center">108 <div class="col-md-5">109 <input type="text" class="form-control" v-model="header.key" placeholder="Header Key">110 </div>111 <div class="col-md-5">112 <input type="text" class="form-control" v-model="header.value" placeholder="Header Value">113 </div>114 <div class="col-md-2">115 <button class="btn btn-outline-danger w-100" @click="removeHeader(index)">116 <i class="bi bi-trash"></i>117 </button>118 </div>119 </div>120 <button class="btn btn-outline-primary add-button" @click="addHeader">121 <i class="bi bi-plus-lg"></i> Agregar Header122 </button>123 </div>124 <!-- Body -->125 <div class="mb-3" v-if="request.method !== 'GET'">126 <label class="form-label">Body</label>127 <textarea class="form-control" rows="5" v-model="request.body" placeholder="Cuerpo de la solicitud"></textarea>128 </div>129 </div>130 </div>131 132 <!-- Aserción del Cuerpo de la Respuesta -->133 <div class="card">134 <div class="card-header">135 <h5>Aserción</h5>136 </div>137 <div class="card-body">138 <div class="form-check form-switch">139 <input class="form-check-input" type="checkbox" id="assertResponseBody" v-model="assertion.enabled">140 <label class="form-check-label" for="assertResponseBody">Activar Aserción</label>141 </div>142 <div class="mt-3" v-if="assertion.enabled">143 <input type="text" class="form-control" v-model="assertion.condition" placeholder="Ejemplo: response.body.data.status is success">144 </div>145 </div>146 </div>147 148 <!-- Sleep -->149 <div class="card">150 <div class="card-header">151 <h5>Sleep</h5>152 </div>153 <div class="card-body">154 <div class="mb-3 row">155 <label class="col-sm-2 col-form-label">Tiempo</label>156 <div class="col-sm-10">157 <input type="text" class="form-control" v-model="sleepTime" placeholder="Ejemplo: 10s">158 </div>159 </div>160 </div>161 </div>162 163 <!-- Repeat -->164 <div class="card">165 <div class="card-header">166 <h5>Repeat</h5>167 </div>168 <div class="card-body">169 <div class="mb-3 row">170 <label class="col-sm-2 col-form-label">Iteraciones</label>171 <div class="col-sm-10">172 <input type="number" class="form-control" v-model.number="repeatCount" min="1">173 </div>174 </div>175 </div>176 </div>177 178 <!-- Call -->179 <div class="card">180 <div class="card-header">181 <h5>Call: Create Payment</h5>182 </div>183 <div class="card-body">184 <div v-for="(param, index) in callParams" :key="index" class="mb-3 row">185 <label class="col-sm-3 col-form-label">{{ param.name }}</label>186 <div class="col-sm-9">187 <input type="text" class="form-control" v-model="param.value">188 </div>189 </div>190 </div>191 </div>192 193 <!-- Result -->194 <div class="card" v-if="result">195 <div class="card-header" :class="{'bg-success text-white': result.success, 'bg-danger text-white': !result.success}">196 <h5>Resultado</h5>197 </div>198 <div class="card-body">199 <p><strong>STATUS:</strong> {{ result.status }}</p>200 <p><strong>Mensaje:</strong> {{ result.message }}</p>201 </div>202 </div>203 204 <!-- Botón de Ejecución -->205 <div class="text-center my-4">206 <button class="btn btn-lg btn-primary" @click="executeTest" :disabled="!validURL">207 <i class="bi bi-play-fill"></i> Ejecutar Prueba208 </button>209 </div>210 211 </div>212 213 <!-- Enlaces a Vue.js y Bootstrap JS -->214 <script src="https://cdn.jsdelivr.net/npm/vue@3.3.4/dist/vue.global.prod.js"></script>215 <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>216 217 <!-- Script Vue.js -->218 <script>219 const { createApp } = Vue;220 221 createApp({222 data() {223 return {224 variables: {225 name: 'user-id',226 value: 'uuid',227 assert: false,228 assertValues: ''229 },230 request: {231 method: 'GET',232 url: '',233 headers: [{ key: 'Authorization', value: '' }],234 body: ''235 },236 assertion: {237 enabled: false,238 condition: ''239 },240 sleepTime: '',241 repeatCount: 1,242 callParams: [243 { name: 'payment-id', value: '[uuid]' },244 { name: 'amount', value: '' },245 { name: 'IBAN', value: 'my-iban' }246 ],247 result: null,248 validURL: true,249 darkTheme: false250 }251 },252 methods: {253 addHeader() {254 this.request.headers.push({ key: '', value: '' });255 },256 removeHeader(index) {257 this.request.headers.splice(index, 1);258 },259 validateURL() {260 try {261 new URL(this.request.url);262 this.validURL = true;263 } catch (_) {264 this.validURL = false;265 }266 },267 executeTest() {268 // Simulación de ejecución de prueba269 this.result = {270 success: true,271 status: 'ACCEPTED',272 message: 'SUBMISSION ID posted: 521-2021-3215-33'273 };274 // Animación de scroll al resultado275 this.$nextTick(() => {276 const resultCard = this.$el.querySelector('.card:last-child');277 resultCard.scrollIntoView({ behavior: 'smooth' });278 });279 },280 toggleTheme() {281 this.darkTheme = !this.darkTheme;282 document.body.classList.toggle('bg-dark', this.darkTheme);283 document.body.classList.toggle('text-white', this.darkTheme);284 }285 },286 mounted() {287 // Inicializar el tema según las preferencias del usuario288 const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;289 if (prefersDark) {290 this.toggleTheme();291 }292 }293 }).mount('#app');294 295 // Manejo del botón de cambio de tema fuera de Vue296 document.getElementById('themeToggle').addEventListener('click', () => {297 document.body.classList.toggle('bg-dark');298 document.body.classList.toggle('text-white');299 const icon = document.getElementById('themeToggle').querySelector('i');300 icon.classList.toggle('bi-moon-fill');301 icon.classList.toggle('bi-sun-fill');302 });303 </script>304 </body>305 </html>306
Enlace
El enlace para compartir es: