← back to Dear Bubbe Nextjs

archived/tests/test-voice-mobile.js

160 lines

const { chromium } = require('playwright');

async function testVoiceMobile() {
  const timestamp = new Date().toISOString();
  console.log(`\n[${timestamp}] ========== Mobile Voice Test ==========`);

  const browser = await chromium.launch({ headless: true });

  try {
    // Test mobile viewport (iPhone 12)
    const context = await browser.newContext({
      viewport: { width: 390, height: 844 },
      userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 14_0 like Mac OS X) AppleWebKit/605.1.15',
      permissions: ['microphone']
    });

    const page = await context.newPage();
    const errors = [];
    const consoleWarnings = [];

    // Capture errors
    page.on('pageerror', error => {
      errors.push(error.message);
      console.log(`❌ Page Error: ${error.message}`);
    });

    // Capture console warnings and errors
    page.on('console', msg => {
      if (msg.type() === 'error') {
        consoleWarnings.push(msg.text());
        console.log(`⚠️  Console Error: ${msg.text()}`);
      }
    });

    console.log('📱 Loading mobile site...');
    await page.goto('http://45.61.58.125:3011', { timeout: 30000 });
    await page.waitForLoadState('networkidle');

    // Take initial screenshot
    await page.screenshot({ path: '/tmp/mobile-before-click.png' });
    console.log('✓ Initial screenshot saved');

    // Check if page loaded
    const title = await page.title();
    console.log(`✓ Page title: ${title}`);

    // Find Let's Chat button
    const chatButton = page.locator('button:has-text("Let\'s Chat"), button:has-text("Stop Listening")').first();
    const buttonExists = await chatButton.count() > 0;

    if (!buttonExists) {
      console.log('❌ FAILED: Let\'s Chat button not found!');
      return { success: false, error: 'Button not found' };
    }

    console.log('✓ Let\'s Chat button found');

    // Get button properties
    const box = await chatButton.boundingBox();
    if (box) {
      console.log(`✓ Button size: ${Math.round(box.width)}x${Math.round(box.height)}px`);

      if (box.height < 44) {
        console.log(`⚠️  WARNING: Button height ${Math.round(box.height)}px is below iOS minimum 44px`);
      }
    }

    // Test button click
    console.log('\n🎤 Testing button click...');
    const beforeText = await chatButton.innerText();
    console.log(`Before click: "${beforeText}"`);

    await chatButton.click();
    await page.waitForTimeout(1000);

    // Check if button state changed
    const afterText = await chatButton.innerText();
    console.log(`After click: "${afterText}"`);

    // Take screenshot after click
    await page.screenshot({ path: '/tmp/mobile-after-click.png' });
    console.log('✓ After-click screenshot saved');

    // Check for voice-related elements
    const overlay = page.locator('[class*="listening"]').first();
    const hasOverlay = await overlay.count() > 0;

    if (hasOverlay) {
      console.log('✓ Listening overlay appeared');
    } else {
      console.log('⚠️  No listening overlay detected');
    }

    // Test voice API endpoint
    console.log('\n🔊 Testing voice API...');
    const apiResponse = await page.evaluate(async () => {
      try {
        const response = await fetch('/api/bubbe-voice', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ text: 'Test', mode: 'bubbe' })
        });

        const blob = await response.blob();
        return {
          status: response.status,
          size: blob.size,
          type: blob.type
        };
      } catch (error) {
        return { error: error.message };
      }
    });

    if (apiResponse.status === 200) {
      console.log(`✓ Voice API working (${apiResponse.size} bytes, ${apiResponse.type})`);
    } else {
      console.log(`❌ Voice API failed: ${JSON.stringify(apiResponse)}`);
    }

    // Summary
    console.log('\n========== Test Summary ==========');
    console.log(`Button found: ${buttonExists ? '✓' : '❌'}`);
    console.log(`Button clickable: ${beforeText !== afterText ? '✓' : '❌'}`);
    console.log(`Voice API: ${apiResponse.status === 200 ? '✓' : '❌'}`);
    console.log(`Page errors: ${errors.length}`);
    console.log(`Console errors: ${consoleWarnings.length}`);

    const success = buttonExists && apiResponse.status === 200 && errors.length === 0;

    if (success) {
      console.log('\n✅ MOBILE VOICE TEST PASSED');
    } else {
      console.log('\n❌ MOBILE VOICE TEST FAILED');
      if (errors.length > 0) {
        console.log('\nErrors:');
        errors.forEach(err => console.log(`  - ${err}`));
      }
    }

    await browser.close();
    return { success, errors, apiResponse };

  } catch (error) {
    console.log(`\n❌ TEST CRASHED: ${error.message}`);
    await browser.close();
    return { success: false, error: error.message };
  }
}

// Run test
testVoiceMobile()
  .then(result => {
    process.exit(result.success ? 0 : 1);
  })
  .catch(error => {
    console.error('Fatal error:', error);
    process.exit(1);
  });