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

# Executar testes E2E noturnos no ambiente 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="Executar testes E2E noturnos no ambiente de staging" description="Agende o Devin para executar sua suíte de testes de ponta a ponta (E2E) no ambiente de staging todas as noites e abrir chamados para as falhas." prompt="Ajude-me a configurar um agendamento noturno do Devin que execute nossa suíte de testes E2E no ambiente de staging. Siga o guia em https://docs.devin.ai/use-cases/gallery/api-scheduled-sessions e me acompanhe em cada etapa: criação de um usuário de serviço, escrita do playbook de testes e criação do agendamento via API." category="Automações" features="API, Agendamentos, Playbooks" />

<div className="uc-detail-wrapper">
  <Tip>Não quer configurar isso manualmente? Cole um link para esta página em uma sessão do Devin e peça para ele configurar tudo para você.</Tip>

  Este guia aborda o gerenciamento de agendamentos por meio da [API v3](/pt-BR/api-reference/v3/overview), útil para fluxos de trabalho de automação e infraestrutura como código. Você também pode criar e gerenciar agendamentos diretamente na [UI do Devin](https://app.devin.ai/settings/schedules?utm_source=docs\&utm_medium=use-case-gallery) sem nenhuma configuração de API.

  <Steps>
    <Step title="Configurar um usuário de serviço para acesso à API">
      Sessões agendadas criadas via API precisam de um usuário de serviço com as permissões corretas. Você configurará um usuário de serviço uma vez e, em seguida, usará sua Chave de API em todas as chamadas abaixo.

      1. Vá para [app.devin.ai](https://app.devin.ai/?utm_source=docs\&utm_medium=use-case-gallery) > **Settings** > **Service Users** e clique em **Create Service User**
      2. Atribua uma função que inclua a permissão `ManageOrgSchedules`
      3. Salve a Chave de API exibida após a criação — ela é mostrada apenas uma vez e você a usará como seu token `Bearer`

      Para obter o **ID da organização**, faça uma chamada ao endpoint [List Organizations](/pt-BR/api-reference/v3/organizations/enterprise-organizations) usando o token do seu usuário de serviço:

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

      Exporte ambos os valores para que os comandos deste guia funcionem exatamente como estão:

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

      Consulte a [documentação de autenticação da API](/pt-BR/api-reference/authentication) para saber mais sobre usuários de serviço e permissões.
    </Step>

    <Step title="Crie um playbook para a execução do teste">
      Before creating the schedule, escreva um [playbook](/pt-BR/product-guides/creating-playbooks) que instrua o Devin exatamente sobre como executar sua suíte E2E e o que fazer com os resultados. Vá para [**Settings > Playbooks**](https://app.devin.ai/settings/playbooks?utm_source=docs\&utm_medium=use-case-gallery) e crie um novo playbook — ou peça ao Devin para gerar um para você a partir de uma descrição do seu fluxo de testes. Aqui está um exemplo de playbook para uma suíte Playwright:

      <PromptBlock type="playbook">
        ```txt Playbook de teste E2E noturno theme={null}
        Você está executando a suíte de testes E2E noturna para acme/web-app no ambiente de staging.

        Steps:
        1. Execute a suíte E2E do Playwright apontando para staging:
           `PLAYWRIGHT_BASE_URL=https://staging.acme.dev npx playwright test --reporter=json`
        2. Analise os resultados JSON. Para cada teste com falha:
           - Crie um ticket no Linear no time "QA" com:
             - Title: "[Nightly E2E] <test name>"
             - Description: a mensagem de erro completa, o stack trace e o caminho do arquivo de teste
             - Label: "nightly-e2e-failure"
             - Priority: High se o teste estiver em tests/critical/*, caso contrário Medium
           - Anexe quaisquer capturas de tela de falha do relatório do Playwright
        3. Se todos os testes passarem, publique um resumo no canal do Slack #qa-results:
           "Nightly E2E: all <N> tests passed against staging (<date>)"
        4. Se houver qualquer teste falhando, publique em #qa-results:
           "Nightly E2E: <N> of <total> tests failed — <count> Linear tickets created"
           Inclua uma lista com os nomes dos testes que falharam.
        ```
      </PromptBlock>

      Anote o ID do playbook após salvar — você vai precisar dele para a chamada de API. Você pode encontrá-lo na URL ao visualizar o playbook (`app.devin.ai/.../playbooks/{playbook_id}`).

      <Tip>Instale a [integração com Linear](/pt-BR/integrations/linear) para que o Devin possa criar tickets como parte do playbook. Ao [criar o agendamento](https://app.devin.ai/settings/schedules/create?utm_source=docs\&utm_medium=use-case-gallery), você também pode definir um **canal do Slack** (por exemplo, `#qa-results`) para que sua equipe seja notificada automaticamente. Dê ao Devin acesso somente leitura aos segredos do seu ambiente de staging (URLs de banco de dados, chaves de API (API keys)) via [organization secrets](/pt-BR/product-guides/secrets) se seus testes precisarem deles.</Tip>
    </Step>

    <Step title="Crie o agendamento noturno pela API">
      Agora use o endpoint `POST /v3/organizations/{org_id}/schedules` para cadastrar o agendamento. Este exemplo é executado todas as noites às 2h 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"
        }'
      ```

      A resposta inclui um `schedule_id` que você usará para gerenciar este agendamento mais tarde. Salve-o:

      ```bash theme={null}
      export SCHEDULE_ID="a1b2c3d4-e5f6-7890-abcd-ef1234567890"  # da resposta
      ```

      O campo `frequency` usa a sintaxe cron padrão. Algumas alternativas úteis:

      | Padrão        | Quando é executado                 |
      | ------------- | ---------------------------------- |
      | `0 2 * * *`   | Todas as noites às 2h UTC          |
      | `0 2 * * 1-5` | Apenas noites de semana (seg–sex)  |
      | `0 6 * * 1`   | Todas as segundas-feiras às 6h UTC |

      Por que 2h? Você quer que os testes sejam executados depois que o último deploy do dia tiver estabilizado em staging, mas cedo o suficiente para que as falhas sejam visíveis quando engenheiros e engenheiras começarem a trabalhar. Ajuste para ficar alinhado ao fuso horário e à cadência de deploy da sua equipe.

      Consulte a [documentação do endpoint Create schedule](/pt-BR/api-reference/v3/schedules/post-organizations-schedules) para ver todos os campos disponíveis.
    </Step>

    <Step title="Revise a primeira execução e ajuste o prompt">
      Depois que o agendamento for acionado pela primeira vez, verifique a sessão para garantir que o Devin executou os testes corretamente e que o resultado corresponde ao que você espera.

      1. Abra o painel do Devin e encontre a sessão em **Past Sessions** — ela estará marcada com o nome do agendamento
      2. A suíte Playwright foi executada? Foram criados tickets no Linear para falhas reais (e não para testes instáveis)?
      3. Verifique o canal do Slack `#qa-results` para ver a mensagem de resumo

      Problemas comuns na primeira execução e como corrigi-los:

      * **O Devin não consegue acessar o ambiente de staging**: Adicione suas variáveis de ambiente de staging (como `STAGING_API_KEY` ou `DATABASE_URL`) como [segredos da organização](/pt-BR/product-guides/secrets), para que fiquem disponíveis em todas as sessões agendadas
      * **Tickets demais causados por testes instáveis**: Adicione uma nova tentativa ao seu playbook: "Execute novamente qualquer teste com falha uma vez antes de abrir um ticket. Só abra tickets para testes que falharem duas vezes."
      * **Os testes demoram demais**: Reduza o escopo da suíte — por exemplo, "Execute apenas os testes em `tests/critical/` e `tests/smoke/`" — ou aumente o tempo limite da sessão

      <PromptBlock agent="advanced">
        ```txt Prompt tweak: filter out flaky tests theme={null}
        Atualize o playbook de E2E noturno: antes de criar um ticket no Linear para
        um teste com falha, execute-o novamente uma vez com `npx playwright test <test-file> --retries=1`.
        Só crie um ticket se o teste falhar na nova tentativa. Adicione o rótulo "flaky"
        a qualquer teste que tiver passado na nova tentativa e mencione isso no resumo no Slack.
        ```
      </PromptBlock>
    </Step>

    <Step title="Gerencie agendamentos como código">
      Depois que sua execução noturna estiver estável, você vai querer gerenciá-la junto com seus outros agendamentos — pausando durante períodos de congelamento de deploy, atualizando o prompt quando sua suíte de testes for alterada ou criando um segundo agendamento para um ambiente diferente.

      **Pausar o agendamento** durante um período de congelamento de deploy ou janela de manutenção:

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

      **Reative-o** quando o período de congelamento acabar:

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

      **Liste todos os agendamentos** para auditar o que está rodando:

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

      Para equipes que gerenciam vários agendamentos, peça ao Devin para criar uma CLI que sincronize definições de agendamentos a partir de um arquivo de configuração YAML — assim você pode versionar seus agendamentos junto com sua configuração de testes:

      <PromptBlock>
        ```txt CLI de agendamentos como código theme={null}
        Escreva um script em Python que leia definições de agendamentos de um arquivo chamado
        devin-schedules.yaml e as sincronize com a Devin API.

        O arquivo YAML deve ter o seguinte formato:
          schedules:
            - title: "E2E noturno — staging"
              prompt: "Execute o conjunto de testes E2E noturno no ambiente de staging."
              frequency: "0 2 * * *"
              playbook_id: "a1b2c3d4e5f6789012345678"
            - title: "E2E noturno — preview"
              prompt: "Execute o conjunto de testes E2E no ambiente de preview."
              frequency: "0 3 * * 1-5"
              playbook_id: "a1b2c3d4e5f6789012345678"

        O script deve:
        1. Comparar as definições do YAML com os agendamentos existentes na API
        2. Criar novos agendamentos, atualizar os que foram alterados e desabilitar agendamentos
           removidos do arquivo
        3. Suportar a opção --dry-run que mostre o que seria alterado
        4. Usar os endpoints em /v3/organizations/{org_id}/schedules
        ```
      </PromptBlock>
    </Step>
  </Steps>
</div>
