|
| 1 | +const fs = require('fs'); |
| 2 | +const path = require('path'); |
| 3 | +const { performance } = require('perf_hooks'); |
| 4 | + |
| 5 | +describe('Experimento IEEE: Resiliencia de UI bajo Latencia Estocástica', () => { |
| 6 | + const markets = ['US', 'CH', 'JP', 'MX']; |
| 7 | + const profiles = ['standard_user', 'performance_glitch_user']; |
| 8 | + |
| 9 | + // Función síncrona para asegurar escritura thread-safe durante la inyección en parallel |
| 10 | + const logIEEEData = (experiment, profile, market, platform, latencyMs) => { |
| 11 | + const timestamp = new Date().toISOString(); |
| 12 | + const csvLine = `${timestamp},${experiment},${profile},${market},${platform},${latencyMs.toFixed(2)}\n`; |
| 13 | + |
| 14 | + // Escribe métricas en la carpeta principal compartida con cypress |
| 15 | + const resultsDir = path.join(__dirname, '..', '..', '..', 'frontend', 'cypress', 'results'); |
| 16 | + const filePath = path.join(resultsDir, 'ieee_latency_data.csv'); |
| 17 | + |
| 18 | + if (!fs.existsSync(resultsDir)) { |
| 19 | + fs.mkdirSync(resultsDir, { recursive: true }); |
| 20 | + } |
| 21 | + |
| 22 | + if (!fs.existsSync(filePath)) { |
| 23 | + fs.writeFileSync(filePath, 'timestamp,experiment,profile,market,platform,latency_ms\n'); |
| 24 | + } |
| 25 | + |
| 26 | + // sync flag asegura write operations en caso que estemos integrando CI paralelismo multihilo |
| 27 | + fs.appendFileSync(filePath, csvLine); |
| 28 | + }; |
| 29 | + |
| 30 | + profiles.forEach((profile) => { |
| 31 | + describe(`Evaluando perfil de inyección: ${profile}`, () => { |
| 32 | + |
| 33 | + markets.forEach((market) => { |
| 34 | + it(`Mide la latencia de renderizado para el mercado ${market}`, async () => { |
| 35 | + |
| 36 | + await device.launchApp({ |
| 37 | + newInstance: true, |
| 38 | + launchArgs: { detoxCountryCode: market } |
| 39 | + }); |
| 40 | + |
| 41 | + // 1. API-Driven State Hydration (Login automatizado) |
| 42 | + await waitFor(element(by.id('screen-login'))).toBeVisible().withTimeout(15000); |
| 43 | + |
| 44 | + await element(by.id('input-username')).typeText(profile); |
| 45 | + await element(by.id('input-password')).typeText('pizza123'); // Preset estándar para dev/qa |
| 46 | + |
| 47 | + // Prevenir keyboard occlusion si la pantalla fue renderizada pequeña |
| 48 | + // Para asegurar consistencia de touch actions en iOS/Android |
| 49 | + await element(by.id('btn-login')).tap(); |
| 50 | + |
| 51 | + // Espera a que estemos dentro de la app (Ej: visualización del View container de catálogo o bottom nav) |
| 52 | + await waitFor(element(by.id('view-bottom-nav'))).toBeVisible().withTimeout(15000); |
| 53 | + |
| 54 | + // 2. Medición precisa de FID proxy en el Checkout Container |
| 55 | + const startTime = performance.now(); |
| 56 | + |
| 57 | + await element(by.id('nav-checkout')).tap(); |
| 58 | + |
| 59 | + // Espera a que complete el mount cycle del market checkout respectivo |
| 60 | + await waitFor(element(by.id('screen-checkout'))).toBeVisible().withTimeout(15000); |
| 61 | + |
| 62 | + const endTime = performance.now(); |
| 63 | + const renderLatency = endTime - startTime; |
| 64 | + |
| 65 | + console.log(`[DATA_POINT] Perfil: ${profile} | Mercado: ${market} | Latencia: ${renderLatency.toFixed(2)} ms`); |
| 66 | + |
| 67 | + // 3. Escribir resultados adjuntando platform: 'mobile' |
| 68 | + logIEEEData('Fuzzy_Wait_States', profile, market, 'mobile', renderLatency); |
| 69 | + }); |
| 70 | + }); |
| 71 | + }); |
| 72 | + }); |
| 73 | +}); |
0 commit comments