> ## 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.

# Exécuter des tests E2E nocturnes en préproduction

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="Lancer des tests E2E nocturnes sur la préproduction" description="Planifiez Devin pour exécuter votre suite de tests E2E sur l'environnement de préproduction chaque nuit et créer des tickets pour chaque échec." prompt="Aidez-moi à configurer une planification nocturne Devin qui exécute notre suite de tests E2E sur la préproduction. Suivez le guide à l’adresse https://docs.devin.ai/use-cases/gallery/api-scheduled-sessions et faites-moi passer par chaque étape : création d’un compte de service, rédaction du playbook de tests et création de la planification via l’API." category="Automatisations" features="API, planifications, playbooks" />

<div className="uc-detail-wrapper">
  <Tip>Vous ne souhaitez pas effectuer cette configuration manuellement ? Collez un lien vers cette page dans une session Devin et demandez-lui de tout configurer pour vous.</Tip>

  Ce guide explique comment gérer les planifications via l'[API v3](/fr/api-reference/v3/overview), ce qui est utile pour les workflows d'automatisation et d'infrastructure-as-code. Vous pouvez également créer et gérer des planifications directement dans l'[interface utilisateur de Devin](https://app.devin.ai/settings/schedules?utm_source=docs\&utm_medium=use-case-gallery) sans aucune configuration d'API.

  <Steps>
    <Step title="Configurer un compte de service pour l’accès à l’API">
      Les sessions planifiées créées via l'API nécessitent un utilisateur de service avec les autorisations appropriées. Vous en configurerez un une seule fois, puis utiliserez son API key dans tous les appels ci-dessous.

      1. Accédez à [app.devin.ai](https://app.devin.ai/?utm_source=docs\&utm_medium=use-case-gallery) > **Settings** > **Service Users** et cliquez sur **Create Service User**
      2. Attribuez un rôle qui inclut l'autorisation `ManageOrgSchedules`
      3. Enregistrez l'API key affichée après la création — elle n'est affichée qu'une seule fois et vous l'utiliserez comme jeton `Bearer`

      Pour obtenir votre **ID d'organisation**, appelez l'endpoint [List Organizations](/fr/api-reference/v3/organizations/enterprise-organizations) avec votre jeton d'utilisateur de service :

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

      Exportez les deux valeurs afin que les commandes de ce guide fonctionnent telles quelles :

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

      Consultez la [documentation sur l’authentification de l’API](/fr/api-reference/authentication) pour plus d’informations sur les comptes de service et leurs autorisations.
    </Step>

    <Step title="Rédigez un playbook pour le test">
      Avant de créer le planning, rédigez un [playbook](/fr/product-guides/creating-playbooks) qui indique à Devin exactement comment exécuter votre suite E2E et quoi faire des résultats. Allez dans [**Settings > Playbooks**](https://app.devin.ai/settings/playbooks?utm_source=docs\&utm_medium=use-case-gallery) et créez un nouveau playbook — ou demandez à Devin d’en générer un à partir d’une description de votre workflow de test. Voici un exemple pour une suite Playwright :

      <PromptBlock type="playbook">
        ```txt Nightly E2E test playbook theme={null}
        You are running the nightly E2E test suite for acme/web-app against staging.

        Steps:
        1. Run the Playwright E2E suite targeting staging:
           `PLAYWRIGHT_BASE_URL=https://staging.acme.dev npx playwright test --reporter=json`
        2. Parse the JSON results. For each failing test:
           - Create a Linear ticket in the "QA" team with:
             - Title: "[Nightly E2E] <test name>"
             - Description: the full error message, stack trace, and the test file path
             - Label: "nightly-e2e-failure"
             - Priority: High if the test is in tests/critical/*, otherwise Medium
           - Attach any failure screenshots from the Playwright report
        3. If all tests pass, post a summary to the #qa-results Slack channel:
           "Nightly E2E: all <N> tests passed against staging (<date>)"
        4. If any tests fail, post to #qa-results:
           "Nightly E2E: <N> of <total> tests failed — <count> Linear tickets created"
           Include a list of the failing test names.
        ```
      </PromptBlock>

      Notez l’ID du playbook après l’avoir enregistré — vous en aurez besoin pour l’appel à l’API. Vous pouvez le trouver dans l’URL lorsque vous affichez le playbook (`app.devin.ai/.../playbooks/{playbook_id}`).

      <Tip>Installez l’[intégration Linear](/fr/integrations/linear) afin que Devin puisse créer des tickets dans le cadre du playbook. Lors de la [création du planning](https://app.devin.ai/settings/schedules/create?utm_source=docs\&utm_medium=use-case-gallery), vous pouvez également définir un **canal Slack** (par exemple, `#qa-results`) pour que votre équipe reçoive automatiquement des notifications. Donnez à Devin un accès en lecture seule aux secrets de votre environnement de staging (URL de base de données, API keys) via les [secrets d’organisation](/fr/product-guides/secrets) si vos tests en ont besoin.</Tip>
    </Step>

    <Step title="Créer la planification nocturne via l’API">
      Utilisez maintenant l’endpoint `POST /v3/organizations/{org_id}/schedules` pour enregistrer la planification. Cet exemple s’exécute chaque nuit à 2 h 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 réponse contient un `schedule_id` que vous utiliserez pour gérer ce planning par la suite. Enregistrez-le :

      ```bash theme={null}
      export SCHEDULE_ID="a1b2c3d4-e5f6-7890-abcd-ef1234567890"  # extrait de la réponse
      ```

      Le champ `frequency` utilise la syntaxe cron standard. Quelques alternatives utiles :

      | Pattern       | When it runs                     |
      | ------------- | -------------------------------- |
      | `0 2 * * *`   | Tous les jours à 2 h (UTC)       |
      | `0 2 * * 1-5` | Du lundi au vendredi à 2 h (UTC) |
      | `0 6 * * 1`   | Tous les lundis à 6 h (UTC)      |

      Pourquoi 2 h ? Vous voulez que les tests s’exécutent une fois que le dernier déploiement de la journée s’est stabilisé sur l’environnement de staging, mais suffisamment tôt pour que les échecs soient visibles lorsque les ingénieurs commencent à travailler. Adaptez ce réglage au fuseau horaire de votre équipe et à votre cadence de déploiement.

      Consultez la [documentation de l’endpoint « Create schedule »](/fr/api-reference/v3/schedules/post-organizations-schedules) pour voir tous les champs disponibles.
    </Step>

    <Step title="Vérifier la première exécution et affiner le prompt">
      Après la première exécution de la planification, vérifiez la session pour vous assurer que Devin a lancé les tests correctement et que les résultats correspondent à ce que vous attendez.

      1. Ouvrez le tableau de bord Devin et trouvez la session sous **Past Sessions** — elle sera étiquetée avec le nom de la planification.
      2. La suite Playwright s’est‑elle exécutée ? Des tickets Linear ont‑ils été créés pour des échecs réels (et non pour des tests instables) ?
      3. Vérifiez le canal Slack `#qa-results` pour le message récapitulatif.

      Problèmes fréquents lors de la première exécution et comment les corriger :

      * **Devin ne peut pas accéder au staging** : ajoutez vos variables d’environnement de staging (comme `STAGING_API_KEY` ou `DATABASE_URL`) en tant que [organization secrets](/fr/product-guides/secrets) afin qu’elles soient disponibles dans chaque session planifiée.
      * **Trop de tickets dus à des tests instables** : ajoutez une nouvelle tentative à votre playbook : « Relancez tout test en échec une fois avant de créer un ticket. Ne créez des tickets que pour les tests qui échouent deux fois. »
      * **Les tests prennent trop de temps** : restreignez la portée de la suite — par exemple : « N’exécutez que les tests dans `tests/critical/` et `tests/smoke/` » — ou augmentez le délai d’expiration de la session.

      <PromptBlock agent="advanced">
        ```txt Prompt tweak: filter out flaky tests theme={null}
        Mettez à jour le playbook E2E nocturne : avant de créer un ticket Linear pour un
        test en échec, relancez‑le une fois avec `npx playwright test <test-file> --retries=1`.
        Créez un ticket uniquement si le test échoue à nouveau. Ajoutez un label "flaky"
        à tout test qui a réussi lors de la relance et mentionnez‑le dans le
        récapitulatif Slack.
        ```
      </PromptBlock>
    </Step>

    <Step title="Gérez les plannings sous forme de code">
      Une fois que votre exécution nocturne est stable, vous voudrez la gérer au même titre que vos autres planifications — la mettre en pause pendant les gels de déploiement, mettre à jour le prompt lorsque votre suite de tests évolue, ou configurer une deuxième planification pour un environnement différent.

      **Mettez la planification en pause** pendant un gel de déploiement ou une fenêtre de maintenance :

      ```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}'
      ```

      **Réactivez-la** une fois le gel terminé :

      ```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}'
      ```

      **Répertoriez toutes les planifications** pour vérifier ce qui est en cours d'exécution :

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

      Pour les équipes qui gèrent plusieurs plannings, demandez à Devin de créer un CLI qui synchronise les définitions de plannings à partir d’un fichier de configuration YAML, afin que vous puissiez placer vos plannings sous gestion de versions en même temps que votre configuration de test :

      <PromptBlock>
        ```txt Schedules-as-code CLI theme={null}
        Write a Python script that reads schedule definitions from a file called
        devin-schedules.yaml and syncs them to the Devin API.

        The YAML file should look like:
          schedules:
            - title: "Nightly E2E — staging"
              prompt: "Run the nightly E2E suite against staging."
              frequency: "0 2 * * *"
              playbook_id: "a1b2c3d4e5f6789012345678"
            - title: "Nightly E2E — preview"
              prompt: "Run the E2E suite against the preview environment."
              frequency: "0 3 * * 1-5"
              playbook_id: "a1b2c3d4e5f6789012345678"

        The script should:
        1. Compare the YAML definitions against existing schedules from the API
        2. Create new schedules, update changed ones, and disable schedules
           removed from the file
        3. Support a --dry-run flag that shows what would change
        4. Use the endpoints at /v3/organizations/{org_id}/schedules
        ```
      </PromptBlock>
    </Step>
  </Steps>
</div>
