Pular para o conteúdo

Referência da CLI fp

O binário fp executa workspaces do Fetchpier sem Electron. Oferece saída interativa no terminal, relatórios legíveis por máquina, códigos de saída estáveis e uma API programática para Node.js.

Um workspace é uma pasta que contém .fetchpier/settings.json. As requisições são os arquivos .http dentro da sua pasta requests/; os ambientes são as pastas dentro de environments/.

ComandoDescriçãoPrecisa de workspace
fp run [paths...]Alias de fp request run.Sim
fp request run [paths...]Executa arquivos .http e/ou pastas. Sem path, executa o requests/ do workspace.Sim
fp env listImprime o nome da pasta de cada ambiente, um por linha — os nomes que --env aceita.Sim
fp env currentImprime o ambiente que uma execução selecionaria (--env > FETCHPIER_ENV > default).Sim
fp init [name] [--template rest|graphql]Cria um workspace em ./<name>, ou na pasta atual quando name é omitido, com uma requisição inicial (rest por padrão).Não
fp --help, fp <command> --helpAjuda do programa ou de um comando.Não
fp -V, fp --versionImprime a identidade, a versão e o aviso de copyright da CLI.Não

Quando um comando precisa de um workspace e nenhum é encontrado, ele sai com o código 4.

fp --version imprime o nome do produto, a versão da CLI e a linha de copyright do projeto no stdout. Invocar fp sem argumentos imprime o mesmo banner acima do texto de uso no stderr e mantém o código de saída de uso. Nenhuma outra invocação imprime um banner, então um relatório JSON redirecionado do stdout nunca é precedido por um. O número de versão da CLI é independente do da aplicação desktop.

  • Sem path: todos os arquivos .http dentro da pasta requests/ do workspace, recursivamente — o mesmo conjunto a partir de qualquer diretório, dentro ou fora do workspace.

  • Paths explícitos (arquivos ou pastas, quantos você quiser) são relativos ao diretório atual, como em qualquer outra ferramenta de linha de comando, então o autocompletar do shell sempre produz um argumento válido. Se um path não existe no diretório atual mas existe dentro do workspace, o erro sugere o path a digitar:

    $ fp run requests/auth/login.http --workspace my-api
    Error: Path not found: requests/auth/login.http
    Did you mean my-api/requests/auth/login.http? Paths are relative to the current directory.
  • As pastas são percorridas em ordem de nome; .runs/, .fetchpier/ e .git/ são ignoradas.

  • Um arquivo .http pode conter várias requisições (separadores ###); apenas a primeira é executada, com um aviso que nomeia o arquivo.

  • Uma pasta de destino (ou o requests/ do workspace) sem nenhum arquivo .http para a execução com o código de saída 19: uma execução que não envia nada não é um sucesso.

fp init cria .fetchpier/, um ambiente default com uma variável baseUrl, requests/example.http e um .gitignore (só se não existir nenhum). Arquivos existentes nunca são sobrescritos, e ele falha com o código de saída 4 se o destino já for um workspace. Ao final, imprime o comando a executar em seguida (fp run --workspace my-api, ou fp run ao inicializar a pasta atual), que funciona exatamente como impresso a partir do mesmo diretório.

OpçãoEfeito
-w, --workspace <path>Seleciona o workspace explicitamente.
-e, --env <name>Seleciona um ambiente pelo nome da pasta (sem diferenciar maiúsculas).
--env-var KEY=VALUESobrescreve uma variável nesta execução; repetível. Um script que depois define a mesma variável prevalece a partir de então.
--persist-envSalva as mudanças de variáveis feitas por scripts (fp.environment.set / remove) nos valores locais, exatamente como o desktop. Sem ela, valem apenas para o resto da execução.
--bailPara após a primeira requisição falha — teste falho, erro de script, arquivo sem requisição, ou uma requisição que não obteve resposta.
--delay <ms>Espera entre requisições (número inteiro, 0 ou mais).
--timeout <ms>Timeout por requisição. Padrão 30000 (30 s, como no desktop); 0 o desativa — a única forma de fazê-lo.
--proxy <url>Envia todas as requisições por este proxy (http://user:pass@host:port). Prevalece sobre HTTPS_PROXY / HTTP_PROXY.
--no-proxyIgnora HTTPS_PROXY / HTTP_PROXY / NO_PROXY nesta execução. Não pode ser combinada com --proxy.
--insecureDesativa a verificação de certificados TLS nesta execução.
--reporter-json <file>Escreve JSON; use - para stdout, o que silencia o reporter para humanos.
--reporter-json-no-bodyOmite os bodies de resposta do JSON.
--reporter-junit <file>Escreve JUnit XML.
--reporter-html <file>Escreve um relatório HTML independente.
--reporter-html-only-failuresAbre o relatório HTML com o filtro de falhas já aplicado.
--save-historyRegistra cada requisição que obteve resposta no histórico do workspace (requests/.runs/), como o log de atividade do desktop.
--suppress-exit-codeRetorna 0 para resultados da execução; erros fatais de preparação continuam não-zero.
--show-secretsNão redige credenciais nem cookies na saída. Use com cuidado.
--asciiUsa ASCII em vez de glifos Unicode.
--no-colorDesativa as cores ANSI; NO_COLOR e FORCE_COLOR também são respeitadas.
--silentSuprime o stdout, mantendo o stderr.
-v, -vv, -vvvAumenta a verbosidade (veja abaixo).

--timeout e --delay aceitam números inteiros de 0 a 2147483647 (o limite de timers do runtime, cerca de 24,8 dias); qualquer outro valor é um erro de uso (saída 3). Uma opção de valor único passada duas vezes mantém o último valor, a convenção habitual da linha de comando — dois --reporter-json escrevem apenas o último.

Os níveis são cumulativos e são os mesmos para uma ou várias requisições:

NívelAcrescenta
padrãoAs linhas de requisição e resposta, e toda a saída fp.log / warn / error dos scripts.
-vA lista de testes de cada requisição, a URL completa em vez do path, e se ela foi via proxy ou direct.
-vvCabeçalhos de requisição e resposta.
-vvvBodies de requisição e resposta, cada um cortado em 64 KB (o relatório JSON tem o body completo).

A redação e o mascaramento de segredos se aplicam em todos os níveis. Um body binário nunca é despejado no terminal: -vvv imprime em vez disso uma linha com seu tamanho e tipo (uma resposta comprimida que foi decodificada é avaliada pelo conteúdo decodificado). O restante do texto é impresso como recebido.

  • Workspace: --workspace > FETCHPIER_WORKSPACE > busca ascendente por uma pasta que contenha .fetchpier/settings.json, começando no diretório atual e parando acima do seu diretório home.
  • Ambiente: --env > FETCHPIER_ENV > default, comparado sem diferenciar maiúsculas com o nome da pasta do ambiente. A CLI nunca lê a preferência de ambiente ativo do desktop, o que mantém o CI previsível.
  • Variáveis: valores do ambiente, depois valores locais por máquina, depois sobrescritas de --env-var, depois o que scripts anteriores da execução tiverem definido. Referências {{$env.NAME}} se resolvem a partir de um arquivo .env na raiz do workspace e, depois, do ambiente do processo.

fp env list imprime um aviso para qualquer pasta de ambiente cujo config.json não possa ser lido. fp env current imprime o nome que uma execução selecionaria sem verificar se ele existe; uma execução com um ambiente desconhecido sai com o código 6 e lista os disponíveis, e uma cujo config.json não possa ser lido sai com o código 4 nomeando o arquivo. Como o desktop, fp run e fp env list mantêm o nome de exibição de um ambiente alinhado com sua pasta: se o name em config.json não corresponde à pasta (por exemplo, depois de renomear a pasta à mão), eles reescrevem esse único campo.

VariávelFinalidade
FETCHPIER_WORKSPACEPasta do workspace, quando --workspace não é informado.
FETCHPIER_ENVNome da pasta do ambiente, quando --env não é informado.
FETCHPIER_WORKSPACE_KEYChave do workspace (FPK1-…) usada para descriptografar variáveis secretas.
HTTPS_PROXY / HTTP_PROXYProxy para destinos https / http.
NO_PROXYDestinos que se conectam diretamente.
NO_COLORDesativa as cores (o mesmo que --no-color).
FORCE_COLORForça as cores quando o stdout não é um terminal (0 não força).

Variáveis e segredos durante uma execução

Section titled “Variáveis e segredos durante uma execução”

Variáveis entre requisições. Um valor que um script define com fp.environment.set (ou remove com fp.environment.remove) se aplica a todas as requisições posteriores da mesma execução — o token de um login chega à chamada seguinte. Um valor definido sob o nome de uma variável secreta continua mascarado como {secret:<name>} em todos os lugares. Sem --persist-env, nada é escrito no workspace.

Variáveis ausentes. Um {{var}} sem valor no ambiente escolhido é enviado literalmente, e um {{$env.NAME}} que nem o .env nem o ambiente do processo definem é enviado vazio; cada caso imprime um aviso (também no relatório JSON, com um code estável) para a requisição que o usa. Nenhum dos dois faz a execução falhar — verifique os avisos, ou faça asserções sobre a resposta, para que uma credencial ausente faça um pipeline falhar. Um nome definido com valor vazio é intencional e não gera aviso. Percent-encoding malformado também gera um aviso e é enviado literalmente.

Segredos em scripts. Apenas os segredos que uma requisição referencia (na URL, cabeçalhos, body ou auth) são descriptografados para ela, então um script que lê um segredo que sua própria requisição não usa recebe undefined. Referencie-o na requisição, ou passe-o por uma variável comum.

Segredos no CI. Forneça a chave do workspace por meio de FETCHPIER_WORKSPACE_KEY, normalmente injetada a partir do cofre de segredos do seu provedor de CI. A resolução é preguiçosa: uma execução que não toca nenhum segredo não precisa de chave. Uma execução que precisa de um segredo que não consegue resolver para antes de enviar, com um código de saída dedicado (14–17).

--persist-env após uma rotação de chave. Se um colega rotacionou a chave do workspace e você puxou essa mudança, seus valores locais continuam criptografados com a chave anterior até você abrir o workspace no app desktop com a nova chave (ele os criptografa novamente). Até lá, fp run --persist-env não salva as escritas de scripts em variáveis secretas, imprime um aviso nomeando a causa e a solução, continua usando o valor em memória pelo resto da execução e salva normalmente as escritas em variáveis comuns. Um checkout de CI não tem valores locais, então isso só acontece em uma máquina de desenvolvimento.

Proxy. HTTPS_PROXY se aplica a destinos https e HTTP_PROXY a destinos http (também nas formas em minúsculas); NO_PROXY exclui hosts, sufixos de domínio, entradas host:port ou tudo (*). --proxy sobrescreve ambas as variáveis; --no-proxy ignora as três. O proxy ativo é mostrado no cabeçalho sem credenciais, seguido da lista NO_PROXY quando houver uma. Uma URL de proxy inutilizável para a execução antes de qualquer envio (código de saída 3); um proxy que não responde faz a requisição falhar no relatório.

Cabeçalhos padrão e compressão. Quando uma requisição não os define, a CLI envia User-Agent: Fetchpier-CLI/<version> e Accept-Encoding: gzip, deflate, br. Respostas comprimidas (gzip, deflate, br) são decodificadas; o relatório JSON traz compressedBytes, decompressedBytes e decodingStatus. Um body que não pode ser decodificado é mantido como recebido, com um aviso, e fp.response.json() falha com a causa real.

Bodies binários. Uma requisição cujo body é um arquivo anexado no desktop (preparado em requests/.files/) é enviada exatamente com os bytes desse arquivo, e com o Content-Type do seu tipo de arquivo, a menos que a requisição defina um. Um arquivo ausente, ou uma referência inválida, faz essa requisição falhar como “not run” em vez de enviá-la vazia.

O runner executa os scripts pre-request, aplica auth e variáveis, envia a requisição, captura cookies, executa os scripts post-response e avalia os testes. Ele continua após uma requisição falha, salvo com --bail. Uma requisição que recebeu qualquer resposta — incluindo um 4xx ou 5xx — passa, a menos que um dos seus testes falhe.

Falhas de rede e TLS, timeouts, uma interrupção com uma requisição em andamento, erros de script e asserções que falham são resultados de requisição, não falhas internas. A execução segue para a próxima requisição (ou para, com --bail), o resumo é gerado e cada relatório configurado ainda é escrito — a execução que mais precisa ser inspecionada é aquela cujo serviço estava fora do ar. Condições que impedem uma execução de sequer começar — um workspace, ambiente ou path ausente, uma configuração ilegível, um proxy inutilizável, uma chave de workspace ausente — continuam fatais e mantêm seus próprios códigos de saída.

Uma requisição que não obteve resposta aparece como no response: <reason> (inalcançável, TLS, timeout, proxy); uma que nunca foi tentada aparece como not run: <reason> (um arquivo sem requisição, um script pre-request que falhou, um arquivo binário ausente ou cuja referência é inválida). Um timeout expirado é reportado como timed out after <limit>.

Uma única execução pode escrever JSON, JUnit XML e HTML independente ao mesmo tempo. O JSON é versionado para consumidores; o JUnit funciona com os dashboards de testes de CI mais comuns; o HTML funciona offline e inclui filtros de tema e de falhas. Os destinos dos relatórios precisam apontar para um diretório pai existente.

  • Só JSON aceita stdout. --reporter-json - escreve no stdout; passar - para qualquer outro reporter é rejeitado com uma mensagem clara (código de saída 2) em vez de criar silenciosamente um arquivo chamado literalmente -.
  • A versão do schema JSON só muda em mudanças incompatíveis. Ela muda apenas quando um consumidor teria de alterar seu código para continuar parseando o relatório; novos campos opcionais não a alteram.
  • Uma requisição que nunca obteve resposta é sempre uma falha visível. Todo formato a mostra como uma falha com seu motivo — nunca como uma entrada simplesmente ausente, e nunca como um grupo vazio que um dashboard leria como aprovado.

Redação. Relatórios e saída do terminal redigem Authorization / Proxy-Authorization, a credencial de auth por API key (query ou cabeçalho) e os valores de Cookie / Set-Cookie. --show-secrets os revela, mas variáveis secretas continuam sendo impressas como {secret:<name>} — inclusive no que um script registra, no nome de um teste ou na mensagem de uma asserção que falhou. Evite publicar relatórios que contenham dados de requisições ou respostas de produção.

Limites do mascaramento. Os segredos são mascarados por correspondência exata, como no mascaramento de logs de CI: um servidor que devolve um segredo escapado (dentro de JSON, codificado em URL) ou um script que o transforma (aplica hash, codifica, recorta) não é reconhecido, e um segredo muito curto pode mascarar texto não relacionado que o contenha. Prefira segredos de tamanho realista.

O runner aplica a configuração TLS do workspace exatamente como o desktop: os certificados de CA e os certificados de cliente listados no bloco tls de .fetchpier/settings.json, cujos arquivos ficam em .fetchpier/certs/ (ambos normalmente são gerenciados nas configurações de workspace do desktop e versionados junto com o workspace). Um certificado de cliente é apresentado aos hosts para os quais está configurado; uma passphrase que referencia uma variável secreta é descriptografada com FETCHPIER_WORKSPACE_KEY. Certificados configurados apenas nas configurações do próprio app desktop não são visíveis para o runner. --insecure desativa a verificação de certificados em uma execução.

O histórico fica desligado por padrão na automação. --save-history registra cada requisição que obteve resposta em requests/.runs/ — um registro local de depuração, ignorado pelo Git por padrão. Como o log de atividade do desktop, ele oculta Authorization, mas mantém API keys e valores de cookies como foram enviados: não o envie como artefato de CI. Os relatórios são o artefato de CI, e eles redigem esses valores.

CódigoSignificado
0Sucesso.
1Uma requisição falhou (teste falho, erro de script, sem resposta, ou um arquivo sem requisição), ou um erro de uso (comando ou opção desconhecidos, fp sem argumentos). Uma execução com requisições falhas nunca reporta sucesso, mesmo que não declare asserções.
2Um destino de saída de relatório é inválido (diretório ausente, ou - para um reporter que não seja JSON).
3Valor de flag inválido (--timeout, --delay), uma URL de proxy inutilizável (flag ou variável), ou --proxy junto com --no-proxy.
4Workspace não encontrado ou inválido — incluindo um .fetchpier/settings.json ou o config.json do ambiente selecionado que não pode ser parseado; ou fp init em uma pasta que já é um workspace.
5Um path de entrada não existe ou não é um arquivo/pasta .http; ou o workspace não tem pasta requests/.
6Ambiente não encontrado.
7--env-var malformado; esperado KEY=VALUE.
8Reservado para erros fatais de parse. Um arquivo que não pode ser parseado em uma requisição é reportado como requisição falha (saída 1).
9Reporter desconhecido (alcançável apenas pela API programática).
10–13Reservados para erros de multipart. Hoje, um problema de multipart é reportado como requisição falha com seu motivo (saída 1).
14Um segredo referenciado precisa ser descriptografado, mas FETCHPIER_WORKSPACE_KEY não está definida.
15A chave do workspace está malformada ou não corresponde a este workspace.
16Um valor secreto não pode ser descriptografado.
17Um segredo referenciado não tem valor definido (“precisa de valor”).
18O runtime Node.js é mais antigo que o mínimo da CLI (22.19.0).
19Nada a executar: uma pasta de destino (ou o requests/ do workspace) não contém nenhum arquivo .http. Não é mascarado por --suppress-exit-code.
130Interrompido por Ctrl-C ou SIGTERM, depois de gravar os relatórios parciais.
255Erro interno; reporte-o como bug.

Interromper uma execução cancela a requisição em andamento e grava os relatórios parciais antes de sair com 130 — sem stack trace, porque uma interrupção é um resultado intencional. As requisições já concluídas são reportadas normalmente.

O pacote suporta consumidores ESM e CommonJS:

import { run, init, listEnvironments, currentEnvironment } from '@fetchpier/cli'
// No paths: the workspace's requests/ tree, from any working directory.
const summary = await run({ paths: [], workspace: '/path/to/ws', silent: true })
console.log(summary.summary.requests) // { total, passed, failed }
console.log(summary.summary.tests) // { total, passed, failed }

run retorna o RunSummary estruturado (o schema do reporter JSON) e nunca chama process.exit — seu código decide o que fazer com o resultado. paths explícitos são relativos ao diretório atual do processo. Por padrão, run também imprime o relatório de terminal no stdout; passe silent: true ou seus próprios reporters para evitar isso. Condições fatais (workspace, path, ambiente, segredos) rejeitam a promise em vez de retornar um resumo; um CliError traz seu código de saída em exitCode.

GitHub Actions — workspace na pasta api/ do repositório:

- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
- run: npm install -g @fetchpier/cli
- run: mkdir -p reports && fp run --env ci --reporter-junit reports/fp.xml
env:
FETCHPIER_WORKSPACE: ${{ github.workspace }}/api
FETCHPIER_WORKSPACE_KEY: ${{ secrets.FETCHPIER_WORKSPACE_KEY }}
- if: always()
uses: actions/upload-artifact@v4
with: { name: fetchpier-report, path: reports/fp.xml }

GitLab CI — workspace na raiz do repositório:

api-tests:
image: node:22
script:
- npm install -g @fetchpier/cli
- fp run --reporter-junit report.xml
artifacts:
when: always
reports:
junit: report.xml

Para executar um subconjunto, passe um path relativo ao diretório de trabalho do job, por exemplo fp run api/requests/smoke.

Os scripts pre- e post-request rodam no mesmo sandbox, com a mesma API fp.*, que no desktop. O sandbox evita erros acidentais em scripts; não é uma defesa contra um adversário que colocou código malicioso no seu workspace. Se você executa coleções não confiáveis no CI, rode fp dentro de um contêiner ou de outra barreira de isolamento.

A CLI atual não troca nem altera a seleção de ambiente do desktop (fp env switch não faz parte desta release: o desktop guarda seu ambiente ativo no próprio armazenamento de dados do usuário, fora do workspace), não renomeia nem duplica ambientes, não importa schemas, não envia URLs ad-hoc, não instala completions de shell, não executa requisições em paralelo e não aceita um arquivo de CA por execução. Configure o material TLS compartilhado no workspace e use o desktop para importar schemas e manter ambientes.