> ## Documentation Index
> Fetch the complete documentation index at: https://docs.devin.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Ejecutar pruebas E2E nocturnas en el entorno de staging

export const UseCaseHero = ({title, description, prompt, category, features, devinUrl, agent, intent, playbookId, type}) => {
  const encodedPrompt = encodeURIComponent(prompt || '');
  const tag = 'docs-use-case-gallery';
  const utm = 'utm_source=docs&utm_medium=use-case-gallery&utm_campaign=hero-cta';
  const agentParams = (agent ? '&agent=' + agent : '') + (intent ? '&intent=' + intent : '') + (playbookId ? '&playbookId=' + playbookId : '');
  const devinHref = type === 'schedule' ? 'https://app.devin.ai/settings/schedules/create?' + utm + agentParams + (prompt ? '&prompt=' + encodedPrompt : '') : type === 'review' ? 'https://app.devin.ai/review?' + utm : agent === 'ada' ? 'https://app.devin.ai/search?' + utm + '&noSubmit=true' + (prompt ? '&prompt=' + encodedPrompt : '') : devinUrl ? devinUrl.includes('?') ? devinUrl + '&' + utm + agentParams : devinUrl + '?' + utm + agentParams : prompt ? 'https://app.devin.ai/?tags=' + tag + '&' + utm + agentParams + '&prompt=' + encodedPrompt : 'https://app.devin.ai/?' + utm + agentParams;
  const buttonLabel = type === 'schedule' ? 'Schedule in Devin ↗' : type === 'review' ? 'Set Up Devin Review ↗' : agent === 'advanced' ? 'Try in Devin ↗' : agent === 'dana' ? 'Try in Dana ↗' : agent === 'ada' ? 'Try in Ask Devin ↗' : 'Try in Devin ↗';
  const featureList = features ? features.split(',').map(f => f.trim()) : [];
  return <div className="uc-hero">
      <div className="uc-hero-inner">
        <div className="uc-hero-left">
          <h1 className="uc-hero-title">{title}</h1>
          <p className="uc-hero-desc">{description}</p>
          <div>
            <a href={devinHref} target="_blank" rel="noopener noreferrer" className="try-in-devin-btn">
              {buttonLabel}
            </a>
          </div>
        </div>
        <div className="uc-hero-meta">
          <div className="uc-meta-item">
            <span className="uc-meta-label">Author</span>
            <span className="uc-meta-value">Cognition</span>
          </div>
          <div className="uc-meta-item">
            <span className="uc-meta-label">Category</span>
            <span className="uc-meta-value">{category}</span>
          </div>
          {featureList.length > 0 && <div className="uc-meta-item">
              <span className="uc-meta-label">Features</span>
              <span className="uc-meta-value">{featureList.join(', ')}</span>
            </div>}
        </div>
      </div>
    </div>;
};

export const PromptBlock = ({children, type, agent, intent, playbookId}) => {
  var utm = 'utm_source=docs&utm_medium=use-case-gallery&utm_campaign=prompt-block';
  var tag = 'docs-use-case-gallery';
  var agentParams = (agent ? '&agent=' + agent : '') + (intent ? '&intent=' + intent : '') + (playbookId ? '&playbookId=' + playbookId : '');
  var label = type === 'schedule' ? 'Schedule in Devin' : type === 'playbook' ? 'Create Playbook' : type === 'knowledge' ? 'Add to Knowledge' : agent === 'advanced' ? 'Try in Devin' : agent === 'dana' ? 'Try in Dana' : agent === 'ada' ? 'Try in Ask Devin' : 'Try in Devin';
  var buildUrl = function (text) {
    var encoded = encodeURIComponent(text);
    if (type === 'schedule') return 'https://app.devin.ai/settings/schedules/create?' + utm + agentParams + '&prompt=' + encoded;
    if (type === 'playbook') return 'https://app.devin.ai/settings/playbooks/create?' + utm + '&body=' + encoded;
    if (type === 'knowledge') return 'https://app.devin.ai/knowledge?' + utm + '&body=' + encoded;
    if (agent === 'ada') return 'https://app.devin.ai/search?' + utm + '&noSubmit=true&prompt=' + encoded;
    return 'https://app.devin.ai/?tags=' + tag + '&' + utm + agentParams + '&prompt=' + encoded;
  };
  const ref = React.useRef(null);
  const [href, setHref] = React.useState('#');
  React.useEffect(() => {
    if (!ref.current) return;
    var codeEl = ref.current.querySelector('pre code');
    if (codeEl) {
      var text = codeEl.textContent.trim();
      if (text) setHref(buildUrl(text));
    }
    var header = ref.current.querySelector('[data-component-part="code-block-header"]');
    if (header && !header.querySelector('.prompt-block-devin-link')) {
      var link = document.createElement('a');
      link.href = href;
      link.target = '_blank';
      link.rel = 'noopener noreferrer';
      link.className = 'prompt-block-devin-link';
      link.style.cssText = 'display:inline-flex;align-items:center;gap:6px;text-decoration:none;color:#fff;font-size:11px;font-weight:500;padding:4px 10px;border-radius:6px;white-space:nowrap;background:#317CFF;transition:background 0.2s;margin-left:8px;';
      link.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"/><polyline points="15 3 21 3 21 9"/><line x1="10" y1="14" x2="21" y2="3"/></svg> ' + label;
      link.onmouseenter = function () {
        link.style.background = '#2968D9';
      };
      link.onmouseleave = function () {
        link.style.background = '#317CFF';
      };
      header.appendChild(link);
    }
    var existingLink = ref.current.querySelector('.prompt-block-devin-link');
    if (existingLink && href !== '#') existingLink.href = href;
  });
  return <div className="prompt-block" ref={ref}>{children}</div>;
};

<UseCaseHero title="Ejecutar pruebas E2E nocturnas en staging" description="Programa a Devin para ejecutar cada noche tu suite de pruebas de extremo a extremo contra staging y crear tickets para los fallos." prompt="Ayúdame a configurar una programación nocturna de Devin que ejecute nuestra suite de pruebas E2E contra staging. Sigue la guía en https://docs.devin.ai/use-cases/gallery/api-scheduled-sessions y guíame paso a paso: crear un usuario de servicio, escribir el playbook de pruebas y crear la programación mediante la API." category="Automatizaciones" features="API, Programaciones, Playbooks" />

<div className="uc-detail-wrapper">
  <Tip>¿Prefieres no configurarlo manualmente? Pega un enlace a esta página en una sesión de Devin y pídele que lo configure todo por ti.</Tip>

  Esta guía explica cómo gestionar programaciones a través de la [API v3](/es/api-reference/v3/overview), lo cual resulta útil para flujos de trabajo de automatización e infraestructura como código. También puede crear y gestionar programaciones directamente en la [interfaz de usuario de Devin](https://app.devin.ai/settings/schedules?utm_source=docs\&utm_medium=use-case-gallery) sin ninguna configuración de API.

  <Steps>
    <Step title="Configura un usuario de servicio para acceder a la API">
      Las sesiones programadas creadas a través de la API necesitan un usuario de servicio con los permisos adecuados. Lo configurarás una sola vez y luego usarás su API key en todas las llamadas que se muestran a continuación.

      1. Ve a [app.devin.ai](https://app.devin.ai/?utm_source=docs\&utm_medium=use-case-gallery) > **Settings** > **Service Users** y haz clic en **Create Service User**
      2. Asigna un rol que incluya el permiso `ManageOrgSchedules`
      3. Guarda la API key que se muestra después de crearlo: solo se muestra una vez y la usarás como tu token `Bearer`

      Para obtener tu **organization ID**, llama al endpoint [List Organizations](/es/api-reference/v3/organizations/enterprise-organizations) con el token de tu usuario de servicio:

      ```bash theme={null}
      curl "https://api.devin.ai/v3/enterprise/organizations" \
        -H "Authorization: Bearer $DEVIN_API_KEY"
      ```

      Exporta ambos valores para que los comandos de esta guía funcionen tal como se muestran:

      ```bash theme={null}
      export DEVIN_API_KEY="sk-your-service-user-key"
      export ORG_ID="your-org-id"
      ```

      Consulta la [documentación de autenticación de la API](/es/api-reference/authentication) para obtener más información sobre los usuarios de servicio y sus permisos.
    </Step>

    <Step title="Crea un playbook para la ejecución de prueba">
      Antes de crear la programación, escribe un [playbook](/es/product-guides/creating-playbooks) que indique a Devin exactamente cómo ejecutar tu suite E2E y qué hacer con los resultados. Ve a [**Settings > Playbooks**](https://app.devin.ai/settings/playbooks?utm_source=docs\&utm_medium=use-case-gallery) y crea un nuevo playbook, o pídele a Devin que genere uno para ti a partir de una descripción de tu flujo de pruebas. Aquí tienes un ejemplo para una suite de Playwright:

      <PromptBlock type="playbook">
        ```txt Nightly E2E test playbook theme={null}
        Estás ejecutando la suite de pruebas E2E nocturna para acme/web-app contra el entorno de staging.

        Pasos:
        1. Ejecuta la suite E2E de Playwright apuntando a staging:
           `PLAYWRIGHT_BASE_URL=https://staging.acme.dev npx playwright test --reporter=json`
        2. Analiza los resultados en formato JSON. Para cada prueba fallida:
           - Crea un ticket en Linear en el equipo "QA" con:
             - Title: "[Nightly E2E] <test name>"
             - Description: el mensaje de error completo, el stack trace y la ruta al archivo de prueba
             - Label: "nightly-e2e-failure"
             - Priority: High si la prueba está en tests/critical/*, en caso contrario Medium
           - Adjunta cualquier captura de pantalla de fallos del informe de Playwright
        3. Si todas las pruebas pasan, publica un resumen en el canal de Slack #qa-results:
           "E2E nocturnas: las <N> pruebas pasaron contra el entorno de staging (<date>)"
        4. Si alguna prueba falla, publica en #qa-results:
           "E2E nocturnas: <N> de <total> pruebas fallaron — se crearon <count> tickets en Linear"
           Incluye una lista con los nombres de las pruebas que fallaron.
        ```
      </PromptBlock>

      Toma nota del ID del playbook después de guardarlo: lo necesitarás para la llamada a la API. Puedes encontrarlo en la URL cuando veas el playbook (`app.devin.ai/.../playbooks/{playbook_id}`).

      <Tip>Instala la [integración con Linear](/es/integrations/linear) para que Devin pueda crear tickets como parte del playbook. Al [crear la programación](https://app.devin.ai/settings/schedules/create?utm_source=docs\&utm_medium=use-case-gallery), también puedes configurar un **canal de Slack** (por ejemplo, `#qa-results`) para que tu equipo reciba notificaciones automáticamente. Concede a Devin acceso de solo lectura a los secrets de tu entorno de staging (URL de bases de datos, API keys) mediante [organization secrets](/es/product-guides/secrets) si tus pruebas los necesitan.</Tip>
    </Step>

    <Step title="Crear la programación nocturna mediante la API">
      Ahora utiliza el endpoint `POST /v3/organizations/{org_id}/schedules` para registrar la programación. Este ejemplo se ejecuta todas las noches a las 2:00 a. m. UTC:

      ```bash theme={null}
      curl -X POST "https://api.devin.ai/v3/organizations/$ORG_ID/schedules" \
        -H "Authorization: Bearer $DEVIN_API_KEY" \
        -H "Content-Type: application/json" \
        -d '{
          "title": "Nightly E2E — staging",
          "prompt": "Run the nightly E2E test suite against staging. Follow the playbook exactly.",
          "schedule_type": "recurring",
          "frequency": "0 2 * * *",
          "playbook_id": "your-playbook-id"
        }'
      ```

      La respuesta incluye un `schedule_id` que usarás para gestionar esta programación más adelante. Guárdalo:

      ```bash theme={null}
      export SCHEDULE_ID="a1b2c3d4-e5f6-7890-abcd-ef1234567890"  # de la respuesta
      ```

      El campo `frequency` usa la sintaxis estándar de cron. Algunas alternativas útiles:

      | Pattern       | When it runs                        |
      | ------------- | ----------------------------------- |
      | `0 2 * * *`   | Cada noche a las 2 a. m. (UTC)      |
      | `0 2 * * 1-5` | Solo noches de lunes a viernes      |
      | `0 6 * * 1`   | Todos los lunes a las 6 a. m. (UTC) |

      ¿Por qué a las 2 a. m.? Quieres que las pruebas se ejecuten después de que el último despliegue del día se haya asentado en el entorno de staging, pero lo bastante temprano como para que los errores sean visibles cuando los ingenieros empiecen a trabajar. Ajústalo para que coincida con la zona horaria y la cadencia de despliegues de tu equipo.

      Consulta la [documentación del endpoint Create schedule](/es/api-reference/v3/schedules/post-organizations-schedules) para ver todos los campos disponibles.
    </Step>

    <Step title="Revisa la primera ejecución y ajusta el prompt">
      Después de que la tarea programada se ejecute por primera vez, revisa la sesión para asegurarte de que Devin haya ejecutado las pruebas correctamente y que el resultado coincida con lo que esperas.

      1. Abre el panel de control de Devin y encuentra la sesión en **Past Sessions** — estará etiquetada con el nombre de la programación
      2. ¿Se ejecutó la suite de Playwright? ¿Se crearon tickets de Linear para fallos reales (no pruebas inestables)?
      3. Revisa el canal de Slack `#qa-results` para ver el mensaje de resumen

      Problemas comunes en la primera ejecución y cómo solucionarlos:

      * **Devin can't access staging**: Agrega tus variables de entorno de staging (como `STAGING_API_KEY` o `DATABASE_URL`) como [organization secrets](/es/product-guides/secrets) para que estén disponibles en cada sesión programada
      * **Too many tickets from flaky tests**: Agrega un reintento a tu playbook: "Vuelve a ejecutar cualquier prueba fallida una vez antes de crear un ticket. Crea tickets solo para las pruebas que fallen dos veces."
      * **Tests take too long**: Acota el alcance de la suite — p. ej., "Solo ejecuta pruebas en `tests/critical/` y `tests/smoke/`" — o aumenta el tiempo de espera de la sesión

      <PromptBlock agent="advanced">
        ```txt Ajuste del prompt: filtrar pruebas inestables theme={null}
        Actualiza el playbook E2E nocturno: antes de crear un ticket de Linear para una
        prueba fallida, vuelve a ejecutarla una vez con `npx playwright test <test-file> --retries=1`.
        Crea un ticket solo si la prueba falla en el reintento. Agrega una etiqueta "flaky" a cualquier
        prueba que haya pasado en el reintento y menciónala en el resumen de Slack.
        ```
      </PromptBlock>
    </Step>

    <Step title="Gestiona las programaciones como código">
      Una vez que tu ejecución nocturna sea estable, querrás gestionarla junto con el resto de tus programaciones: pausarla durante congelaciones de despliegue, actualizar el prompt cuando cambie tu suite de pruebas o crear una segunda programación para un entorno diferente.

      **Pausa la programación** durante una congelación de despliegue o una ventana de mantenimiento:

      ```bash theme={null}
      curl -X PATCH "https://api.devin.ai/v3/organizations/$ORG_ID/schedules/$SCHEDULE_ID" \
        -H "Authorization: Bearer $DEVIN_API_KEY" \
        -H "Content-Type: application/json" \
        -d '{"enabled": false}'
      ```

      **Vuelve a habilitarla** cuando finalice el período de congelación:

      ```bash theme={null}
      curl -X PATCH "https://api.devin.ai/v3/organizations/$ORG_ID/schedules/$SCHEDULE_ID" \
        -H "Authorization: Bearer $DEVIN_API_KEY" \
        -H "Content-Type: application/json" \
        -d '{"enabled": true}'
      ```

      **Enumera todas las programaciones** para auditar qué se está ejecutando:

      ```bash theme={null}
      curl "https://api.devin.ai/v3/organizations/$ORG_ID/schedules" \
        -H "Authorization: Bearer $DEVIN_API_KEY"
      ```

      Para equipos que gestionan múltiples programaciones, pídele a Devin que cree una CLI que sincronice las definiciones de programaciones a partir de un archivo de configuración YAML, para que puedas someter tus programaciones a control de versiones junto con tu configuración de pruebas:

      <PromptBlock>
        ```txt Schedules-as-code CLI theme={null}
        Escribe un script en Python que lea las definiciones de programaciones desde un archivo llamado
        devin-schedules.yaml y las sincronice con la API de Devin.

        El archivo YAML debería tener el siguiente formato:
          schedules:
            - title: "Nightly E2E — staging"
              prompt: "Ejecuta la suite E2E nocturna contra staging."
              frequency: "0 2 * * *"
              playbook_id: "a1b2c3d4e5f6789012345678"
            - title: "Nightly E2E — preview"
              prompt: "Ejecuta la suite E2E contra el entorno de preview."
              frequency: "0 3 * * 1-5"
              playbook_id: "a1b2c3d4e5f6789012345678"

        El script debería:
        1. Comparar las definiciones del YAML con las programaciones existentes en la API
        2. Crear nuevas programaciones, actualizar las que hayan cambiado y desactivar las
           programaciones eliminadas del archivo
        3. Admitir una opción --dry-run que muestre qué cambiaría
        4. Usar los endpoints en /v3/organizations/{org_id}/schedules
        ```
      </PromptBlock>
    </Step>
  </Steps>
</div>
