Safari representa el 27% del tráfico web móvil, y todos los navegadores de iOS, incluyendo Chrome en iPhone, corren sobre WebKit. Saltear WebKit es saltear a tus usuarios de iPhone. Chrome y Edge comparten el mismo motor Chromium, así que juntos cubren aproximadamente el 78% del tráfico de escritorio con un solo proyecto de navegador. Esta guía cubre cómo organizar la cobertura de navegadores según el riesgo para el usuario, cómo configurar proyectos de Playwright para cada motor, y cómo evitar que el tiempo de CI cross-browser se triplique.

Por qué los navegadores siguen siendo diferentes

Los navegadores modernos (Chrome, Firefox, Safari, Edge) soportan los mismos estándares de HTML, CSS y JavaScript. Pero las diferencias persisten:

Renderizado CSS: gaps de flexbox, comportamientos de grid, renderizado de fuentes, shadow DOM. Los navegadores implementan las especificaciones con pequeñas variaciones. APIs de JavaScript: algunas APIs más nuevas no tienen soporte en versiones anteriores de Safari. Array.at(), structuredClone(), ResizeObserver, todas con soporte variable. Elementos de formulario: selectores de fecha, inputs de archivo, elementos select. Los navegadores los estilizan y los hacen funcionar de forma distinta. Renderizado de PDF: Safari maneja los PDFs diferente a Chrome. Específico de WebKit: iOS usa WebKit en todos los navegadores (sí, Chrome en iPhone usa WebKit por debajo). Safari en Mac equivale a Safari en iPhone.

Cuota de mercado de navegadores (2025)

| Navegador | Escritorio | Móvil |

|-----------|-----------|-------|

| Chrome | ~65% | ~66% |

| Safari | ~12% | ~27% |

| Firefox | ~3% | ~1% |

| Edge | ~13% | ~3% |

Safari es crítico para móvil (iPhone es WebKit). Edge está basado en Chrome (Chromium). Firefox tiene poca cuota de mercado pero importa en entornos corporativos y ciertas regiones.

La estrategia pragmática

No se puede testear todo en todos los navegadores. Una jerarquía práctica:

Nivel 1: siempre testear (cada sprint)

Chrome (mayor cuota de mercado, navegador principal de desarrollo) y Safari (crítico para usuarios de iOS/macOS).

Nivel 2: testear antes de releases importantes

Firefox (menor cuota de mercado pero renderizado diferente) y Edge (basado en Chromium, riesgo adicional bajo).

Nivel 3: testear para funcionalidades específicas

Safari iOS al testear flujos específicos de móvil, Chrome Android para comportamientos específicos de móvil, y versiones específicas de navegador cuando clientes corporativos lo requieren.

Configuración cross-browser en Playwright

Playwright soporta Chrome, Firefox y WebKit (el motor de Safari) de forma nativa:

// playwright.config.ts
import { defineConfig, devices } from '@playwright/test';

export default defineConfig({
  projects: [
    // Navegadores de escritorio
    {
      name: 'chromium',
      use: { ...devices['Desktop Chrome'] },
    },
    {
      name: 'firefox',
      use: { ...devices['Desktop Firefox'] },
    },
    {
      name: 'webkit',
      use: { ...devices['Desktop Safari'] },
    },

    // Navegadores móviles
    {
      name: 'mobile-chrome',
      use: { ...devices['Pixel 7'] },
    },
    {
      name: 'mobile-safari',
      use: { ...devices['iPhone 14'] },
    },
  ],
});

Ejecutar un navegador específico:

npx playwright test --project=webkit

Ejecutar todos los navegadores:

npx playwright test

Qué testear cross-browser (y qué no)

Testear cross-browser

  • Flujos principales del usuario (login, checkout, flujos clave)
  • Formularios, especialmente selectores de fecha, subida de archivos, selects
  • Layouts CSS, sobre todo diseños basados en flex/grid
  • Funcionalidades con JavaScript intensivo (interacciones complejas)
  • Flujos específicos de móvil (touch, viewport, orientación)

No necesita testing cross-browser

  • Tests unitarios, son independientes del navegador
  • Tests de API, no hay navegador involucrado
  • Tests de lógica de backend
  • Herramientas de administración internas que solo usa tu equipo

Manejar fallos específicos de un navegador

Cuando un test falla solo en un navegador:

test('subida de archivos', async ({ page, browserName }) => {
  // Saltear en WebKit: el comportamiento del input de archivo difiere significativamente
  test.skip(browserName === 'webkit', 'WebKit maneja los inputs de archivo diferente');

  await page.goto('/subir');
  await page.setInputFiles('[data-testid="file-input"]', 'test-file.pdf');
  await expect(page.getByTestId('upload-success')).toBeVisible();
});

Cuando necesitás comportamiento específico por navegador:

test('el selector de fecha funciona', async ({ page, browserName }) => {
  await page.goto('/reservar-turno');

  if (browserName === 'webkit') {
    // El selector de fecha de Safari requiere una interacción diferente
    await page.fill('[data-testid="date-input"]', '2026-06-15');
  } else {
    await page.click('[data-testid="date-input"]');
    await page.click('[data-date="2026-06-15"]');
  }

  await expect(page.getByTestId('selected-date')).toContainText('June 15');
});

BrowserStack y Sauce Labs

Los navegadores integrados de Playwright usan versiones open source. Para testear en Chrome real (no Chromium), Safari real y versiones específicas de navegador, se usan servicios de testing en la nube.

BrowserStack

// playwright.config.ts para BrowserStack
const capabilities = {
  'browserstack.user': process.env.BROWSERSTACK_USERNAME,
  'browserstack.key': process.env.BROWSERSTACK_ACCESS_KEY,
};

export default defineConfig({
  projects: [
    {
      name: 'chrome@latest-mac',
      use: {
        connectOptions: {
          wsEndpoint: `wss://cdp.browserstack.com/playwright?caps=${encodeURIComponent(JSON.stringify({
            ...capabilities,
            browserName: 'chrome',
            browserVersion: 'latest',
            'bstack:options': {
              os: 'OS X',
              osVersion: 'Sonoma',
            }
          }))}`,
        },
      },
    },
  ],
});

Cuándo vale la pena un servicio en la nube

  • Necesitas Safari real (no WebKit) en macOS real
  • Una versión específica de Chrome (clientes corporativos bloqueados en Chrome 110)
  • Testing en dispositivos iOS reales (no simulador)
  • Soporte para IE11 (raro, pero todavía existe en finanzas y gobierno)

Testing responsivo

Testear en múltiples tamaños de viewport, no solo móvil vs escritorio:

// playwright.config.ts
projects: [
  {
    name: 'desktop',
    use: { viewport: { width: 1920, height: 1080 } },
  },
  {
    name: 'laptop',
    use: { viewport: { width: 1280, height: 720 } },
  },
  {
    name: 'tablet',
    use: { viewport: { width: 768, height: 1024 } },
  },
  {
    name: 'mobile',
    use: { viewport: { width: 375, height: 667 } },  // iPhone SE
  },
],

Dentro de un test:

test('la navegación funciona en móvil', async ({ page }) => {
  await page.setViewportSize({ width: 375, height: 667 });
  await page.goto('/');

  // Móvil: menú hamburguesa en lugar de barra de navegación
  await expect(page.getByTestId('hamburger-menu')).toBeVisible();
  await expect(page.getByTestId('desktop-nav')).not.toBeVisible();

  await page.getByTestId('hamburger-menu').click();
  await expect(page.getByTestId('mobile-nav')).toBeVisible();
});

Gestionar fallos cross-browser en CI

Correr los navegadores en paralelo para mantener CI rápido:

# Estrategia de matrix en GitHub Actions
strategy:
  matrix:
    browser: [chromium, firefox, webkit]

steps:
  - run: npx playwright test --project=${{ matrix.browser }}

O usar sharding en los tests cross-browser:

strategy:
  matrix:
    include:
      - browser: chromium
        shard: 1/2
      - browser: chromium
        shard: 2/2
      - browser: firefox
        shard: 1/1
      - browser: webkit
        shard: 1/1

Testing visual cross-browser

Las diferencias de renderizado CSS suelen ser sutiles. La comparación manual es costosa. Usa Percy o la comparación de capturas de pantalla de Playwright:

test('la página principal se renderiza correctamente', async ({ page }) => {
  await page.goto('/');
  await expect(page).toHaveScreenshot('homepage.png', {
    maxDiffPixelRatio: 0.02,  // 2% de diferencia de píxeles permitido
  });
});

Las capturas de pantalla se guardan por proyecto: cada navegador tiene su propia línea base.

Estrategia cross-browser práctica

1. Corre el suite completo en Chrome en cada commit

2. Corre Chrome + Safari antes de cada release

3. Corre todos los navegadores (incluyendo Firefox y Edge) antes de releases importantes

4. Testea viewports móviles para funcionalidades responsivas

→ See also: Pruebas Entre Navegadores con Playwright: Chrome, Firefox, Safari | Emulación Móvil en Playwright: Pruebas Responsivas y Táctiles | Ejecución Paralela en Playwright: Workers, Fragmentos y Fragmentación para Mayor Velocidad