Wikipedia para siempre
ShareCode
Permalink: http://www.treeweb.es/u/974/ 01/02/2011

ShareCode

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  .step {17  display: flex;18  align-items: center;19  padding: 8px 12px;20  margin-bottom: 8px;21  position: relative;22  }23  .step:hover {24  background-color: #f8f9fa;25  }26  .step:hover .step-controls {27  display: flex;28  }29  .step-type {30  font-weight: bold;31  color: #0d6efd;32  margin-right: 10px;33  min-width: 60px;34  }35  .step-content {36  flex: 1;37  display: flex;38  align-items: center;39  }40  .step-content input,41  .step-content select,42  .step-content textarea {43  margin-right: 8px;44  }45  .step-controls {46  display: none;47  align-items: center;48  }49  .step-controls button {50  background: none;51  border: none;52  margin-left: 5px;53  color: #6c757d;54  }55  .step-controls button:hover {56  color: #000;57  }58  .add-step {59  text-align: center;60  margin: 20px 0;61  }62  .theme-toggle {63  cursor: pointer;64  }65  .execute-btn {66  background: none;67  border: none;68  color: #198754;69  font-size: 1.2em;70  }71  .execute-btn:hover {72  color: #145c32;73  }74  </style>75 </head>76 <body>77  <!-- Barra de navegación -->78  <nav class="navbar navbar-expand-lg navbar-dark bg-primary">79  <div class="container-fluid">80  <a class="navbar-brand" href="#">81  <!-- Logo -->82  <img src="https://via.placeholder.com/150x40?text=Logo" alt="Logo">83  </a>84  <span class="navbar-text text-white">85  Plataforma de Testing Automatizado de APIs86  </span>87  <button class="btn btn-secondary ms-auto theme-toggle" id="themeToggle">88  <i class="bi bi-moon-fill"></i>89  </button>90  </div>91  </nav>92 93  <!-- Contenido principal -->94  <div id="app" class="container my-4">95  <!-- Lista de pasos -->96  <div v-for="(step, index) in steps" :key="index" class="step">97  <span class="step-type" v-if="step.type === 'variable'">VAR</span>98  <span class="step-type" v-else-if="step.type === 'request'">{{ step.data.method }}</span>99  <span class="step-type" v-else-if="step.type === 'assertion'">ASSERT</span>100 101  <div class="step-content">102  <!-- Contenido según el tipo de paso -->103  <component :is="getStepComponent(step.type)" v-model="step.data"></component>104  </div>105  <div class="step-controls">106  <button @click="moveUp(index)" :disabled="index === 0"><i class="bi bi-arrow-up"></i></button>107  <button @click="moveDown(index)" :disabled="index === steps.length - 1"><i class="bi bi-arrow-down"></i></button>108  <button v-if="step.type === 'request'" @click="executeRequestStep(index)" class="execute-btn"><i class="bi bi-play-circle"></i></button>109  <button @click="removeStep(index)"><i class="bi bi-trash"></i></button>110  </div>111  </div>112 113  <!-- Botones para añadir nuevos pasos -->114  <div class="add-step">115  <button class="btn btn-outline-primary me-2" @click="addStep('variable')">116  <i class="bi bi-sliders"></i> Variable117  </button>118  <button class="btn btn-outline-primary me-2" @click="addStep('request')">119  <i class="bi bi-arrow-up-right-circle"></i> Solicitud HTTP120  </button>121  <button class="btn btn-outline-primary me-2" @click="addStep('assertion')">122  <i class="bi bi-check-circle"></i> Aserción123  </button>124  <!-- Agrega más botones si es necesario -->125  </div>126 127  <!-- Botón de Ejecución -->128  <div class="text-center my-4">129  <button class="btn btn-lg btn-success" @click="executeTest" :disabled="!isExecutable">130  <i class="bi bi-play-fill"></i> Ejecutar Prueba Completa131  </button>132  </div>133 134  <!-- Resultados -->135  <div class="alert" :class="{'alert-success': result?.success, 'alert-danger': !result?.success}" v-if="result">136  <strong>Resultado:</strong> {{ result.message }}137  </div>138  </div>139 140  <!-- Enlaces a Vue.js y Bootstrap JS -->141  <script src="https://cdn.jsdelivr.net/npm/vue@3.3.4/dist/vue.global.prod.js"></script>142  <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>143 144  <!-- Componentes para los pasos -->145  <script>146  const VariableStep = {147  template: `148  <div class="d-flex align-items-center">149  <input type="text" class="form-control me-2" v-model="data.name" placeholder="Nombre" style="max-width: 150px;">150  <span>=</span>151  <input type="text" class="form-control ms-2" v-model="data.value" placeholder="Valor" style="max-width: 150px;">152  </div>153  `,154  props: ['modelValue'],155  computed: {156  data: {157  get() { return this.modelValue; },158  set(value) { this.$emit('update:modelValue', value); }159  }160  }161  };162 163  const RequestStep = {164  template: `165  <div class="d-flex align-items-center flex-wrap">166  <select class="form-select me-2" v-model="data.method" style="max-width: 100px;">167  <option>GET</option>168  <option>POST</option>169  <option>PUT</option>170  <option>DELETE</option>171  </select>172  <input type="text" class="form-control me-2" v-model="data.url" placeholder="URL" style="flex: 1;">173  <!-- Botón para mostrar detalles -->174  <button class="btn btn-sm btn-outline-secondary me-2" @click="toggleDetails">175  <i class="bi" :class="showDetails ? 'bi-chevron-up' : 'bi-chevron-down'"></i>176  </button>177  <!-- Detalles opcionales -->178  <div v-if="showDetails" class="w-100 mt-2">179  <!-- Headers -->180  <button class="btn btn-sm btn-outline-secondary me-2" @click="toggleHeaders">181  <i class="bi" :class="showHeaders ? 'bi-dash' : 'bi-plus'"></i> Headers182  </button>183  <!-- Body -->184  <button class="btn btn-sm btn-outline-secondary" @click="toggleBody" v-if="data.method !== 'GET'">185  <i class="bi" :class="showBody ? 'bi-dash' : 'bi-plus'"></i> Body186  </button>187  <!-- Headers -->188  <div v-if="showHeaders" class="mt-2">189  <div v-for="(header, index) in data.headers" :key="index" class="d-flex align-items-center mb-2">190  <input type="text" class="form-control me-2" v-model="header.key" placeholder="Header Key" style="max-width: 150px;">191  <input type="text" class="form-control me-2" v-model="header.value" placeholder="Header Value" style="max-width: 150px;">192  <button class="btn btn-sm btn-outline-danger" @click="removeHeader(index)">193  <i class="bi bi-trash"></i>194  </button>195  </div>196  <button class="btn btn-outline-primary btn-sm" @click="addHeader">197  <i class="bi bi-plus-lg"></i> Agregar Header198  </button>199  </div>200  <!-- Body -->201  <div v-if="showBody" class="mt-2">202  <label class="form-label">Body</label>203  <textarea class="form-control" rows="3" v-model="data.body" placeholder="Cuerpo de la solicitud"></textarea>204  </div>205  </div>206  </div>207  `,208  props: ['modelValue'],209  data() {210  return {211  showDetails: false,212  showHeaders: false,213  showBody: false,214  }215  },216  computed: {217  data: {218  get() { return this.modelValue; },219  set(value) { this.$emit('update:modelValue', value); }220  }221  },222  methods: {223  toggleDetails() {224  this.showDetails = !this.showDetails;225  },226  toggleHeaders() {227  this.showHeaders = !this.showHeaders;228  },229  toggleBody() {230  this.showBody = !this.showBody;231  },232  addHeader() {233  this.data.headers.push({ key: '', value: '' });234  },235  removeHeader(index) {236  this.data.headers.splice(index, 1);237  }238  }239  };240 241  const AssertionStep = {242  template: `243  <div class="d-flex align-items-center">244  <input type="text" class="form-control" v-model="data.condition" placeholder="Condición">245  </div>246  `,247  props: ['modelValue'],248  computed: {249  data: {250  get() { return this.modelValue; },251  set(value) { this.$emit('update:modelValue', value); }252  }253  }254  };255 256  // Instancia de Vue257  const { createApp } = Vue;258 259  createApp({260  components: {261  'variable-step': VariableStep,262  'request-step': RequestStep,263  'assertion-step': AssertionStep,264  // Agrega más componentes si es necesario265  },266  data() {267  return {268  steps: [],269  result: null,270  darkTheme: false,271  }272  },273  computed: {274  isExecutable() {275  // Verifica si hay al menos un paso para ejecutar276  return this.steps.length > 0;277  }278  },279  methods: {280  getStepComponent(type) {281  switch (type) {282  case 'variable':283  return 'variable-step';284  case 'request':285  return 'request-step';286  case 'assertion':287  return 'assertion-step';288  // Otros casos...289  }290  },291  moveUp(index) {292  if (index > 0) {293  [this.steps[index - 1], this.steps[index]] = [this.steps[index], this.steps[index - 1]];294  }295  },296  moveDown(index) {297  if (index < this.steps.length - 1) {298  [this.steps[index], this.steps[index + 1]] = [this.steps[index + 1], this.steps[index]];299  }300  },301  removeStep(index) {302  this.steps.splice(index, 1);303  },304  addStep(type) {305  let newStep = {306  type: type,307  data: {}308  };309  switch (type) {310  case 'variable':311  newStep.data = { name: '', value: '' };312  break;313  case 'request':314  newStep.data = { method: 'GET', url: '', headers: [], body: '' };315  break;316  case 'assertion':317  newStep.data = { condition: '' };318  break;319  // Otros casos...320  }321  this.steps.push(newStep);322  },323  executeTest() {324  // Simulación de ejecución de prueba completa325  this.result = {326  success: true,327  message: 'Prueba completa ejecutada exitosamente.'328  };329  // Animación de scroll al resultado330  this.$nextTick(() => {331  window.scrollTo({ top: document.body.scrollHeight, behavior: 'smooth' });332  });333  },334  executeRequestStep(index) {335  // Simulación de ejecución individual del paso Request336  alert(`Ejecutando solicitud: ${this.steps[index].data.method} ${this.steps[index].data.url}`);337  // Aquí podrías implementar la lógica para ejecutar solo este paso y mostrar resultados338  }339  },340  mounted() {341  // Inicializar el tema según las preferencias del usuario342  const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;343  if (prefersDark) {344  this.toggleTheme();345  }346  }347  }).mount('#app');348 349  // Manejo del botón de cambio de tema fuera de Vue350  document.getElementById('themeToggle').addEventListener('click', () => {351  document.body.classList.toggle('bg-dark');352  document.body.classList.toggle('text-white');353  const icon = document.getElementById('themeToggle').querySelector('i');354  icon.classList.toggle('bi-moon-fill');355  icon.classList.toggle('bi-sun-fill');356  });357  </script>358 </body>359 </html>360 


Este ShareCode tiene versiones:
  1. Plataforma de Testing Automa... (28/09/2024)
Enlace
El enlace para compartir es: