Mockando requisições com Override no Chrome DevTools

Descubra o poder da função override no Chrome DevTools! Simule respostas e modifique cabeçalhos diretamente no navegador para testar e desenvolver com facilidade.

Mockando requisições com Override no Chrome DevTools
"Mockando" requisições direto no Chrome com a função override do DevTools

Sem dúvida, uma das minhas funcionalidades favoritas do DevTools do Chrome é a função override. Com o override, podemos sobrescrever requisições diretamente no navegador. Por exemplo, se seu frontend faz uma requisição para o backend em um endpoint específico, você pode usar o DevTools para simular uma resposta, mudando o conteúdo (body) e/ou os cabeçalhos (headers) dessa resposta. Isso é muito útil para criar cenários de teste, resolver problemas ou desenvolver o frontend sem precisar de um backend pronto.

Neste texto, você vai encontrar um pequeno projeto de estudo. Na sequência, apresento as etapas para sobrescrever (override) o corpo (body) de uma resposta de requisição e outro exemplo, modificando os cabeçalhos (headers) de resposta. Tudo isso direto no DevTools do Chrome.

Criando um exemplo de estudo

Para demonstrar o uso do override, utilizei um pequeno projeto que é executado com Node.js e o framework Express. Para iniciar o projeto basta executar os seguintes comandos:

# Utilizei a versão 20.12.0 do Node.js.
# Para verificar a versão instalada no
# seu sistema, execute: node --version

# Inicializa um novo pacote NPM com as
# configurações padrão (sem perguntas)
npm init -y

# Instala as dependências necessárias:
# - express: um framework minimalista
#   para construir aplicações web no
#   Node.js.
# - prettier: não é obrigatório para este
#   estudo, mas é uma ferramenta de formatação
#   de código, usada para manter o código
#   consistente e legível. Não afeta a
#   lógica do programa
npm install express prettier

Na sequência modifiquei o arquivo package.json que foi gerado no processo acima adicionando os "scripts" e o "type":

{
 "name": "chrome-override",
 "version": "1.0.0",
 "main": "index.js",
 "scripts": {
  "start": "node src/index.js",
  "format": "npx prettier --write src/**/*.js"
 },
 "type": "module",
 "keywords": [],
 "author": "",
 "license": "ISC",
 "description": "",
 "dependencies": {
  "express": "^4.19.2",
  "prettier": "^3.3.3"
 }
}

package.json

💡
Dentro da propriedade scripts, você associa um nome (chave) a um comando (valor). Então para executar um script, você usa o comandonpm run seguido do nome do script, como npm run format ou npm run start.

Em seguida, criei um arquivo chamado home.html, uma página HTML simples que contém alguns botões. Quando clicados, esses botões fazem chamadas ao backend:

<!doctype html>
<html lang="en">
 <head>
  <meta charset="UTF-8" />
  <meta
   name="viewport"
   content="width=device-width, initial-scale=1.0" />
  <title>consolelog.com.br</title>
 </head>
 <body>
  <button onclick="mostrarListaDeEnderecos()">
   Carregar Lista
  </button>
  <button onclick="loginCorreto()">Login Correto</button>
  <button onclick="loginErrado()">Login Errado</button>

  <script>
   function mostrarNaTela(conteudoTexto) {
    const div = document.createElement("div");
    div.textContent = conteudoTexto;
    document.body.appendChild(div);
   }

   async function mostrarListaDeEnderecos() {
    const url = "/enderecos";
    const resposta = await fetch(url);

    if (!resposta.ok) {
     mostrarNaTela(`Response status: ${resposta.status}`);
     return;
    }

    const enderecos = await resposta.json();
    enderecos.forEach((endereco) =>
     mostrarNaTela(endereco)
    );
   }

   function loginCorreto() {
    login("usuario1", "123");
   }

   function loginErrado() {
    login("usua", "123df");
   }

   async function login(usuario, senha) {
    const url = "/login";
    const resposta = await fetch(url, {
     method: "post",
     headers: {
      "content-type": "application/json",
     },
     body: JSON.stringify({
      usuario,
      senha,
     }),
    });

    if (!resposta.ok) {
     mostrarNaTela(`Response status: ${resposta.status}`);

     return;
    }

    const accessToken =
     resposta.headers.get("access-token");
    mostrarNaTela(`accessToken: ${accessToken}`);
   }
  </script>
 </body>
</html>

home.html

Para completar a estrutura do projeto, criei o arquivo index.js com a configuração do Express e os endpoints que serão usados neste projeto de exemplo:

import express from "express";
import { createReadStream } from "fs";

const app = express();
app.use(express.json());

app.get("/", (_, res) => {
 res.writeHead(200, {
  "content-type": "text/html",
 });

 const streamHomeHtml = createReadStream("./src/home.html");
 streamHomeHtml.pipe(res);
});

app.get("/enderecos", (_, res) => {
 res.json([
  "consolelog.com.br",
  "www.consolelog.com.br",
  "https://consolelog.com.br",
  "https://www.consolelog.com.br",
 ]);
});

app.post("/login", (req, res) => {
 const { usuario, senha } = req.body;
 if (!(usuario === "usuario1" && senha === "123")) {
  res.writeHead(401).end();
  return;
 }

 res
  .writeHead(204, {
   "access-token": "teste access token",
  })
  .end();
});

const port = 3000;
app.listen(port, () => {
 console.log(`Example app listening on port ${port}`);
});

index.js

Testando o projeto

Para executar o projeto basta rodar o comando npm start e testar a aplicação no navegador na porta 3000:

Navegador mostrando o projeto de teste em execução
Projeto em execução

Sobrescrevendo a resposta de uma requisição - override body - Chrome Devtools

Com a aplicação em execução, abra o DevTools do Chrome usando o atalho correspondente:

  • Ctrl + Shift + I no Windows
  • Cmd + Option + I no macOS

Em seguida, vá até a aba Network (Rede) e encontre a requisição que deseja sobrescrever. Para este exemplo, vamos selecionar a requisição para o endpoint /enderecos. Quando encontrar a requisição, clique com o botão direito sobre ela e escolha a opção Override content.

Devtools do navegador mostrando a opção "Override content"
Habilitando o override para um recurso específico

Em seguida, o Chrome solicitará que você selecione um diretório. Esse diretório será usado para salvar tudo o que for sobrescrito. Basta escolher um diretório de sua preferência:

Devtools do Chrome mostra um banner solicitando a seleção de um diretório
Selecionando um diretório para guardar as configurações de override

Após selecionar o diretório, conceda acesso para o Chrome:

Chrome mostra um banner na parte superior solicitando permissão de acesso ao diretório indicado na etapa anterior
Solicitando permissão de acesso ao diretório

Feito isto, o Chrome irá abrir o conteúdo original da sua requisição em modo editável, como a imagem abaixo mostra. Então, para testar, adicionei uma linha conforme a imagem abaixo ilustra e depois pressionei cmd+s (ctrl + s no Windows) para salvar as alterações:

Feito isto, o Chrome exibirá o conteúdo original da sua requisição em um modo editável, conforme mostrado na imagem abaixo. Para testar, adicionei uma linha ("conteudo-simulado.com.br") como ilustrado na imagem e, em seguida, pressionei cmd + s (ou ctrl + s no Windows) para salvar as alterações:

Devtools mostrando o conteúdo atual do recurso /enderecos com a possibilidade de edição (override)
Sobrescrevendo o conteúdo do recurso /enderecos

Para concluir o teste, atualizei a página e cliquei no botão "Carregar Lista". Observe que o corpo da resposta do recurso "/enderecos" agora inclui a linha que adicionamos na etapa anterior. Isso confirma que sobrescrevemos o corpo (body) da resposta da requisição diretamente no navegador, simulando um novo cenário com a linha "conteudo-simulado.com.br":

Navegador mostrando que o conteúdo do recurso /enderecos reflete o conteúdo que foi editado (sobrescrito)
Resultado do override

Indicação de override na aba Network

Para facilitar a nossa vida, as requisições sobrescritas são destacadas na aba "Network" (Rede) com uma bolinha roxa à esquerda do nome do recurso, como mostrado na imagem abaixo. Isso torna mais fácil identificar quais recursos estão sendo testados.

Devtools mostrando uma bolinha roxa no recurso "/enderecos" na aba Network (Rede) indicando o override
Indicação de override

Sobrescrevendo o cabeçalho de resposta - override headers - Chrome Devtools

Seguindo exatamente a mesma configuração acima, também é possível sobrescrever os cabeçalhos de uma requisição. Neste exemplo vou sobrescrever o cabeçalho de resposta access-token do endpoint /login.

Novamente, na aba Network (Rede), localize a requisição e clique com o botão direito do mouse selecionando a opção Override Headers:

Devtools mostrando a opção "Override headers" no recurso "/login" na aba Network (Rede)
Sobrescrevendo os cabeçalhos (headers) de resposta

Após selecionar a opção, o Chrome possibilitará que você edite os cabeçalhos de resposta atuais ou que você inclua um novo. Abaixo editei o cabeçalho Access-Token:

Devtools mostrando a possibilidade de edição ou inclusão dos cabeçalhos de resposta do recurso /login
Modificando o valor do cabeçalho (header) de resposta Access-Token

Por fim, atualizei a página e cliquei no botão Login Correto. Veja que o valor que o cabeçalho de resposta access-token retornou é o valor simulado:

Navegador mostrando o conteúdo do header Access-Token que foi previamente modificado.
Resultado do override do cabeçalho Access-Token

Visualizando os arquivos com as configurações de override

As configurações de override que usamos nos exemplos são salvas no diretório que escolhemos no início deste texto. Além de criar essas configurações diretamente no DevTools, você também pode usar um editor de sua escolha, como o VS Code. Para isso, abra o diretório e edite os arquivos, como mostrado na imagem abaixo.

VS Code mostrando o conteúdo do arquivo "enderecos.json" e ".headers.json"
Arquivos com as configurações do override

Considerações

A possibilidade de sobrescrever respostas e/ou cabeçalhos de APIs no Chrome DevTools é um recurso extremamente útil. Com ele, você pode simular diferentes cenários sem precisar alterar o ambiente de testes/produção/outro(s). É uma ferramenta extremamente útil e com certeza em algum momento será o recurso ideal para você analisar algum tipo de problema de forma rápida e sem gerar impacto para o time, já que toda a configuração de simulação está local.