Creo en nosotros. Wikipedia.
ShareCode
Permalink: http://www.treeweb.es/u/974/ 01/02/2011

ShareCode

1 document.addEventListener('DOMContentLoaded', function() {2  document.getElementById('welcome-modal').classList.remove('hidden');3  makeSortable();4  renderTestTable();5 });6 7 function closeWelcomeModal() {8  document.getElementById('welcome-modal').classList.add('hidden');9 }10 11 const testTable = [12  { my_step: 'GRANTED', expected_status: 200 },13  { my_step: 'PENDING', expected_status: 200 },14  { my_step: 'FINISHED', expected_status: 200 },15  { my_step: 'ERROR', expected_status: 200 },16  { my_step: 'INVALID', expected_status: 400 }17 ];18 19 function renderTestTable() {20  const tbody = document.querySelector('#test-table tbody');21  tbody.innerHTML = '';22  testTable.forEach((testCase, index) => {23  const row = document.createElement('tr');24  row.innerHTML = `25  <td class="border px-4 py-2"><input type="text" value="${testCase.my_step}" onchange="updateTestCase(${index}, 'my_step', this.value)" class="w-full"></td>26  <td class="border px-4 py-2"><input type="number" value="${testCase.expected_status}" onchange="updateTestCase(${index}, 'expected_status', this.value)" class="w-full"></td>27  `;28  tbody.appendChild(row);29  });30 }31 32 function updateTestCase(index, key, value) {33  testTable[index][key] = value;34 }35 36 function addTestCase() {37  testTable.push({ my_step: '', expected_status: '' });38  renderTestTable();39 }40 41 function showInsertMenu(button) {42  const menu = document.createElement('div');43  menu.classList.add('absolute', 'bg-white', 'shadow-md', 'rounded', 'mt-2', 'z-10');44  menu.innerHTML = `45  <ul class="space-y-2 p-2">46  <li><button type="button" onclick="insertVariable(this)" class="bg-blue-500 text-white px-4 py-2 rounded">+ Variable</button></li>47  <li><button type="button" onclick="insertRequest(this)" class="bg-blue-500 text-white px-4 py-2 rounded">+ Request</button></li>48  <li><button type="button" onclick="insertAssert(this)" class="bg-blue-500 text-white px-4 py-2 rounded">+ Assert</button></li>49  <li><button type="button" onclick="insertSleep(this)" class="bg-blue-500 text-white px-4 py-2 rounded">+ Sleep</button></li>50  </ul>51  `;52  button.parentElement.appendChild(menu);53 54  document.addEventListener('click', function(event) {55  if (!menu.contains(event.target) && !button.contains(event.target)) {56  menu.remove();57  }58  }, { once: true });59 }60 61 function insertElement(button, elementFunction) {62  const container = button.closest('#elements-list');63  const buttonDiv = button.parentElement;64  const newElement = elementFunction();65  container.insertBefore(newElement, buttonDiv.nextSibling);66  button.parentElement.querySelector('.absolute').remove();67  addInsertButton(container, buttonDiv.nextSibling);68 }69 70 function insertVariable(button) {71  insertElement(button, createVariableElement);72 }73 74 function insertRequest(button) {75  insertElement(button, createRequestElement);76 }77 78 function insertAssert(button) {79  insertElement(button, createAssertElement);80 }81 82 function insertSleep(button) {83  insertElement(button, createSleepElement);84 }85 86 function createVariableElement() {87  const div = document.createElement('div');88  div.classList.add('element', 'bg-white', 'p-4', 'rounded-lg', 'shadow-md', 'flex', 'items-center', 'space-x-4');89  div.innerHTML = `90  <span class="text-gray-700">Variable</span>91  <input type="text" placeholder="Nombre" class="flex-1 p-2 border border-gray-300 rounded" />92  <input type="text" placeholder="Valor" class="flex-1 p-2 border border-gray-300 rounded" />93  <button type="button" onclick="removeElement(this)" class="text-red-500">x</button>94  <button type="button" onclick="duplicateElement(this)" class="text-blue-500">⧉</button>95  `;96  return div;97 }98 99 function createRequestElement() {100  const div = document.createElement('div');101  div.classList.add('element', 'bg-white', 'p-4', 'rounded-lg', 'shadow-md', 'flex', 'items-center', 'space-x-4');102  div.innerHTML = `103  <span class="text-gray-700">Request</span>104  <select class="flex-1 p-2 border border-gray-300 rounded">105  <option>GET</option>106  <option>POST</option>107  <option>PUT</option>108  <option>DELETE</option>109  </select>110  <input type="text" placeholder="URL" class="flex-1 p-2 border border-gray-300 rounded" />111  <textarea placeholder="Headers" class="flex-1 p-2 border border-gray-300 rounded"></textarea>112  <textarea placeholder="Body" class="flex-1 p-2 border border-gray-300 rounded"></textarea>113  <button type="button" onclick="removeElement(this)" class="text-red-500">x</button>114  <button type="button" onclick="duplicateElement(this)" class="text-blue-500">⧉</button>115  `;116  return div;117 }118 119 function createAssertElement() {120  const div = document.createElement('div');121  div.classList.add('element', 'bg-white', 'p-4', 'rounded-lg', 'shadow-md', 'space-y-4');122  div.innerHTML = `123  <span class="text-gray-700">Assert</span>124  <div class="flex items-center space-x-4">125  <input type="text" placeholder="Referencia" class="flex-1 p-2 border border-gray-300 rounded assert-reference" list="references-datalist"/>126  <datalist id="references-datalist">127  <option value="response.status">128  <option value="response.headers.Content-Type">129  <option value="response.body.user.name">130  </datalist>131  <select class="flex-1 p-2 border border-gray-300 rounded" onchange="updateAssertInput(this)">132  <option value="equals">Igual a</option>133  <option value="not_equals">Distinto a</option>134  <option value="in_list">En lista</option>135  <option value="not_in_list">No en lista</option>136  </select>137  <input type="text" placeholder="Valor" class="flex-1 p-2 border border-gray-300 rounded assert-value" />138  <button type="button" onclick="removeElement(this)" class="text-red-500">x</button>139  <button type="button" onclick="duplicateElement(this)" class="text-blue-500">⧉</button>140  </div>141  `;142  return div;143 }144 145 function createSleepElement() {146  const div = document.createElement('div');147  div.classList.add('element', 'bg-white', 'p-4', 'rounded-lg', 'shadow-md', 'flex', 'items-center', 'space-x-4');148  div.innerHTML = `149  <span class="text-gray-700">Sleep</span>150  <input type="number" placeholder="Segundos" class="flex-1 p-2 border border-gray-300 rounded" />151  <button type="button" onclick="removeElement(this)" class="text-red-500">x</button>152  <button type="button" onclick="duplicateElement(this)" class="text-blue-500">⧉</button>153  `;154  return div;155 }156 157 function addInsertButton(container, afterElement) {158  const buttonDiv = document.createElement('div');159  buttonDiv.classList.add('flex', 'justify-center', 'my-2');160  buttonDiv.innerHTML = `161  <button type="button" onclick="showInsertMenu(this)" class="bg-gray-200 text-gray-600 px-2 py-1 rounded">+</button>162  `;163  container.insertBefore(buttonDiv, afterElement);164 }165 166 function duplicateElement(button) {167  const container = button.closest('#elements-list');168  const element = button.parentElement.cloneNode(true);169  container.insertBefore(element, button.parentElement.nextSibling);170  addInsertButton(container, button.parentElement.nextSibling);171 }172 173 function removeElement(button) {174  const container = button.closest('#elements-list');175  button.parentElement.remove();176  if (!container.lastElementChild || !container.lastElementChild.querySelector('button')) {177  addInsertButton(container);178  }179 }180 181 function saveTest() {182  const elements = [];183  const listItems = document.getElementById('elements-list').children;184  for (let i = 0; i < listItems.length; i++) {185  const element = listItems[i];186  if (!element.querySelector('span')) continue; // Skip insert buttons187  const type = element.querySelector('span').textContent;188  if (type === 'Variable') {189  const name = element.children[1].value;190  const value = element.children[2].value;191  if (name && value) {192  elements.push({ type, name, value });193  } else {194  alert('Please fill out both name and value for all variables.');195  return;196  }197  } else if (type === 'Request') {198  const method = element.children[1].value;199  const url = element.children[2].value;200  const headers = element.children[3].value;201  const body = element.children[4].value;202  if (method && url) {203  elements.push({ type, method, url, headers, body });204  } else {205  alert('Please fill out method and URL for all requests.');206  return;207  }208  } else if (type === 'Assert') {209  const assertType = element.children[2].value;210  const reference = element.children[1].value;211  const value = element.children[3].value;212  if (reference && value) {213  elements.push({ type, assertType, reference, value });214  } else {215  alert('Please fill out reference and value for all asserts.');216  return;217  }218  } else if (type === 'Sleep') {219  const seconds = element.children[1].value;220  if (seconds) {221  elements.push({ type, seconds });222  } else {223  alert('Please fill out the number of seconds for all sleeps.');224  return;225  }226  }227  }228  console.log('Elements:', elements);229  alert('Test saved!');230 }231 232 function updateAssertInput(select) {233  const valueInput = select.parentElement.querySelector('.assert-value');234  if (select.value === 'in_list' || select.value === 'not_in_list') {235  valueInput.placeholder = 'Valores (separados por comas)';236  } else {237  valueInput.placeholder = 'Valor';238  }239 }240 241 function makeSortable() {242  const container = document.getElementById('elements-list');243  Sortable.create(container, {244  handle: '.element',245  animation: 150,246  onEnd: function (evt) {247  if (!container.lastElementChild || !container.lastElementChild.querySelector('button')) {248  addInsertButton(container);249  }250  },251  });252 }253 254 document.getElementById('start-execution').addEventListener('click', startExecution);255 256 const environments = {257  Local: {258  origin: 'http://localhost:8080',259  user_id: '12345',260  app_id: 'abcd1234'261  },262  Staging: {263  origin: 'https://staging.myservice.com',264  user_id: '67890',265  app_id: 'wxyz5678'266  }267 };268 269 async function startExecution() {270  const logContainer = document.getElementById('execution-log');271  logContainer.innerHTML = ''; // Clear previous logs272 273  const selectedEnvironment = document.getElementById('environment-select').value;274  const variables = environments[selectedEnvironment];275 276  const steps = [277  {278  type: 'request',279  method: 'PATCH',280  url: '{{ origin }}/thing/{{ my-thing }}',281  headers: {},282  body: {283  step: '{{ my_step }}'284  },285  asserts: [286  { path: 'response.status', operator: 'equals', value: '{{ expected_status }}' }287  ]288  },289  // Add more steps here...290  ];291 292  for (const testCase of testTable) {293  const testVariables = { ...variables, ...testCase };294  logContainer.innerHTML += `<div class="log-entry"><p><strong>Executing test case:</strong> ${JSON.stringify(testCase)}</p></div>`;295  for (const step of steps) {296  let logEntry = document.createElement('div');297  logEntry.classList.add('log-entry');298  logEntry.innerHTML = `<p><strong>${step.method}</strong> ${replaceVariables(step.url, testVariables)}</p>`;299  logContainer.appendChild(logEntry);300 301  try {302  const response = await executeStep(step, testVariables);303  logEntry.classList.add('success');304  logEntry.innerHTML += `<p>Response: ${JSON.stringify(response)}</p>`;305 306  if (step.asserts) {307  for (const assert of step.asserts) {308  const result = evaluateAssert(response, assert, testVariables);309  if (!result.passed) {310  throw new Error(`Assert failed: ${result.message}`);311  }312  }313  }314  } catch (error) {315  logEntry.classList.add('error');316  logEntry.innerHTML += `<p>Error: ${error.message}</p>`;317  break; // Stop execution on error318  }319  }320  }321 }322 323 async function executeStep(step, variables) {324  const url = replaceVariables(step.url, variables);325  const headers = Object.keys(step.headers).reduce((acc, key) => {326  acc[key] = replaceVariables(step.headers[key], variables);327  return acc;328  }, {});329  const body = step.body ? JSON.stringify(replaceVariables(JSON.stringify(step.body), variables)) : null;330 331  const options = {332  method: step.method,333  headers: headers,334  body: body335  };336 337  const response = await fetch(url, options);338 339  if (!response.ok) {340  throw new Error(`HTTP error! status: ${response.status}`);341  }342 343  const data = await response.json();344  return { status: response.status, headers: response.headers, body: data };345 }346 347 function replaceVariables(template, variables) {348  return template.replace(/{{s*([^}]+)s*}}/g, (match, p1) => variables[p1.trim()] || match);349 }350 351 function evaluateAssert(response, assert, variables) {352  const value = getValueFromPath(response, assert.path);353  const expectedValue = replaceVariables(assert.value, variables);354  let passed = false;355  let message = '';356 357  switch (assert.operator) {358  case 'equals':359  passed = value == expectedValue;360  message = `${assert.path} should be ${expectedValue}, but was ${value}`;361  break;362  case 'is_not':363  passed = value != expectedValue;364  message = `${assert.path} should not be ${expectedValue}, but was ${value}`;365  break;366  // Add more operators as needed367  default:368  message = `Unknown operator ${assert.operator}`;369  }370 371  return { passed, message };372 }373 374 function getValueFromPath(obj, path) {375  return path.split('.').reduce((acc, part) => acc && acc[part], obj);376 }377 
Enlace
El enlace para compartir es: