1 <!DOCTYPE html>2 <html lang="en">3 <head>4 <meta charset="UTF-8">5 <meta name="viewport" content="width=device-width, initial-scale=1.0">6 <title>Flowtest Execution</title>7 <link href="https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css" rel="stylesheet">8 </head>9 <body class="bg-gray-100">10 <div class="container mx-auto p-4">11 <h1 class="text-2xl font-bold mb-4">Flowtest Execution</h1>12 <div class="mb-4">13 <label for="environment-select" class="block text-gray-700">Select Environment:</label>14 <select id="environment-select" class="mt-1 block w-full p-2 border border-gray-300 rounded">15 <option value="Local">Local</option>16 <option value="Staging">Staging</option>17 <!-- Add more environments as needed -->18 </select>19 </div>20 <div id="execution-log" class="space-y-4">21 <!-- Logs of requests execution will be appended here -->22 </div>23 <button id="start-execution" class="bg-green-500 text-white px-4 py-2 rounded mt-4">Start Execution</button>24 </div>25 26 <script srdddc="execution.js">27 28 document.getElementById('start-execution').addEventListener('click', startExecution);29 30 const environments = {31 Local: {32 origin: 'http://localhost:8080',33 user_id: '12345',34 app_id: 'abcd1234'35 },36 Staging: {37 origin: 'https://staging.myservice.com',38 user_id: '67890',39 app_id: 'wxyz5678'40 }41 };42 43 async function startExecution() {44 const logContainer = document.getElementById('execution-log');45 logContainer.innerHTML = ''; // Clear previous logs46 47 const selectedEnvironment = document.getElementById('environment-select').value;48 const variables = environments[selectedEnvironment];49 50 const steps = [51 {52 type: 'request',53 method: 'GET',54 url: '{{ origin }}/users/{{ user_id }}?format=json',55 headers: {56 'Application-ID': '{{ app_id }}'57 },58 body: null,59 asserts: [60 { path: 'response.body.counter', operator: 'is_not', value: 0 }61 ]62 },63 // Add more steps here...64 ];65 66 for (const step of steps) {67 let logEntry = document.createElement('div');68 logEntry.classList.add('log-entry');69 logEntry.innerHTML = `<p><strong>${step.method}</strong> ${replaceVariables(step.url, variables)}</p>`;70 logContainer.appendChild(logEntry);71 72 try {73 const response = await executeStep(step, variables);74 logEntry.classList.add('success');75 logEntry.innerHTML += `<p>Response: ${JSON.stringify(response)}</p>`;76 77 if (step.asserts) {78 for (const assert of step.asserts) {79 const result = evaluateAssert(response, assert);80 if (!result.passed) {81 throw new Error(`Assert failed: ${result.message}`);82 }83 }84 }85 } catch (error) {86 logEntry.classList.add('error');87 logEntry.innerHTML += `<p>Error: ${error.message}</p>`;88 break; // Stop execution on error89 }90 }91 }92 93 async function executeStep(step, variables) {94 const url = replaceVariables(step.url, variables);95 const headers = Object.keys(step.headers).reduce((acc, key) => {96 acc[key] = replaceVariables(step.headers[key], variables);97 return acc;98 }, {});99 const body = step.body ? JSON.stringify(replaceVariables(JSON.stringify(step.body), variables)) : null;100 101 const options = {102 method: step.method,103 headers: headers,104 body: body105 };106 107 const response = await fetch(url, options);108 109 if (!response.ok) {110 throw new Error(`HTTP error! status: ${response.status}`);111 }112 113 const data = await response.json();114 // Update variables based on response if necessary115 return { status: response.status, headers: response.headers, body: data };116 }117 118 function replaceVariables(template, variables) {119 return template.replace(/{{s*([^}]+)s*}}/g, (match, p1) => variables[p1.trim()] || match);120 }121 122 function evaluateAssert(response, assert) {123 const value = getValueFromPath(response, assert.path);124 let passed = false;125 let message = '';126 127 switch (assert.operator) {128 case 'is_not':129 passed = value !== assert.value;130 message = `${assert.path} should not be ${assert.value}, but was ${value}`;131 break;132 // Add more operators as needed133 default:134 message = `Unknown operator ${assert.operator}`;135 }136 137 return { passed, message };138 }139 140 function getValueFromPath(obj, path) {141 return path.split('.').reduce((acc, part) => acc && acc[part], obj);142 }143 144 </script>145 </body>146 </html>147
Enlace
El enlace para compartir es: