@gdias-tools/gmail-api-utils
v2.0.0
Published
Gmail API utilities for reliable email and OTP tests in Cypress and Playwright
Maintainers
Readme
@gdias-tools/gmail-api-utils
Utilitários da API do Gmail para validar e-mails reais em testes com Cypress e Playwright. Busque mensagens, leia o conteúdo da caixa de entrada, aguarde o e-mail enviado durante o teste e extraia códigos temporários sem expor as credenciais OAuth ao navegador.
English: read the English README.
O pacote requer Node.js 22 ou superior. Os adaptadores dos frameworks usam o mesmo cliente Gmail, para que a busca e a leitura de OTP tenham o mesmo comportamento no Cypress e no Playwright.
Instalação
npm install @gdias-tools/gmail-api-utilsCompatibilidade da versão 2
A versão 2 requer Node.js 22 ou superior e usa o fetch nativo do Node, sem dependências de execução. O pacote não carrega arquivos .env automaticamente; carregue-os no projeto de testes (por exemplo, com dotenv/config) ou configure as variáveis no cofre de segredos do CI.
Acesso ao Gmail
Crie credenciais OAuth para uma conta Gmail dedicada a testes, ative a Gmail API e conceda o escopo somente leitura https://www.googleapis.com/auth/gmail.readonly. Defina estas variáveis no processo que inicia o executor de testes:
GMAIL_CLIENT_ID=...
GMAIL_CLIENT_SECRET=...
GMAIL_REFRESH_TOKEN=...Mantenha os valores no ambiente local ou no cofre de segredos do CI. Não os versione nem os coloque em variáveis Cypress acessíveis pelo navegador. O Google pode expirar ou revogar refresh tokens; apps OAuth com publicação no estado Testing podem emitir tokens que expiram após sete dias.
Cliente Gmail
const GmailService = require("@gdias-tools/gmail-api-utils");
const gmail = new GmailService({
clientId: process.env.GMAIL_CLIENT_ID,
clientSecret: process.env.GMAIL_CLIENT_SECRET,
refreshToken: process.env.GMAIL_REFRESH_TOKEN,
});
const startedAt = new Date();
await solicitarEmailDeLogin();
const { code, message } = await gmail.waitForOtp({
from: "[email protected]",
to: "[email protected]",
subject: "Your sign-in code",
after: startedAt,
pattern: /\b\d{6}\b/,
timeoutMs: 60_000,
});
console.log("OTP recebido na mensagem", message.id);
await enviarCodigoNaAplicacao(code);Registre after imediatamente antes da ação que envia o e-mail. Em testes paralelos, use um alias de destinatário ou outros critérios de busca exclusivos para cada cenário. O Gmail retorna as mensagens mais recentes primeiro, mas uma caixa compartilhada não consegue identificar qual teste gerou mensagens idênticas.
Cypress
Registre as tarefas no processo Node do Cypress e os comandos no arquivo de suporte. As credenciais OAuth ficam no Node.
cypress.config.js:
const { defineConfig } = require("cypress");
const { registerCypressTasks } = require("@gdias-tools/gmail-api-utils/cypress");
module.exports = defineConfig({
e2e: {
setupNodeEvents(on, config) {
registerCypressTasks(on);
return config;
},
},
});cypress/support/e2e.js:
const { registerCypressCommands } = require("@gdias-tools/gmail-api-utils/cypress/support");
registerCypressCommands(Cypress);Exemplo de teste:
const startedAt = new Date();
cy.get('[data-testid="request-code"]').click();
cy.gmailWaitForOtp({
from: "[email protected]",
to: "[email protected]",
after: startedAt,
pattern: "\\b\\d{6}\\b",
timeoutMs: 60_000,
}).then(({ code }) => {
cy.get('[data-testid="otp"]').type(code);
cy.get('[data-testid="submit"]').click();
});Os comandos disponíveis são gmailSearchMessages, gmailGetMessage, gmailWaitForMessage e gmailWaitForOtp. Como as tarefas do Cypress recebem dados serializáveis, informe a expressão do OTP como string. A tarefa de OTP retorna o código e os metadados da mensagem; use gmailGetMessage explicitamente quando o teste precisar inspecionar o corpo completo.
Playwright
Adicione o fixture gmail ao objeto test do Playwright. Ao chamar um método de espera, o fixture aumenta o timeout do teste para cobrir o tempo configurado para o e-mail chegar:
const { test: base, expect } = require("@playwright/test");
const { extendWithGmail } = require("@gdias-tools/gmail-api-utils/playwright");
const test = extendWithGmail(base);
test("faz login com o código recebido por e-mail", async ({ page, gmail }) => {
const startedAt = new Date();
await page.goto("/login");
await page.getByLabel("Email").fill("[email protected]");
await page.getByRole("button", { name: "Send code" }).click();
const { code } = await gmail.waitForOtp({
from: "[email protected]",
to: "[email protected]",
after: startedAt,
pattern: /\b\d{6}\b/,
});
await page.getByLabel("Verification code").fill(code);
await page.getByRole("button", { name: "Continue" }).click();
await expect(page.getByText("Welcome")).toBeVisible();
});API
searchMessages(options)retorna IDs e informações de paginação. Aceitafrom,to,subject,after,beforee a sintaxe de busca do Gmail emquery.getMessage(messageId)retorna cabeçalhos, data, snippet e conteúdo decodificado em texto e HTML. Partes MIME aninhadas são percorridas recursivamente.waitForMessage(options)consulta o Gmail até uma mensagem correspondente chegar outimeoutMsser atingido. AceitaintervalMs,excludeIdseAbortSignalno uso direto pelo Node.waitForOtp(options)aguarda uma mensagem com opatternconfigurado e retorna{ code, match, message }. O padrão inicial procura um código de seis dígitos.updateAccessToken(),getLastEmailIdBySender(),getEmailById()egetEmailSnippet()continuam disponíveis para usuários das versões anteriores. As chamadas ao Gmail renovam o access token automaticamente.
Timeouts geram EmailWaitTimeoutError (code: "EMAIL_WAIT_TIMEOUT"). Falhas do Gmail e OAuth geram GmailApiError com um code estável e, quando disponível, o status HTTP. A biblioteca não registra tokens, conteúdo das mensagens ou OTPs nos logs.
Contribuições
Issues e pull requests são bem-vindos. Execute npm test dentro do diretório do pacote antes de abrir um pull request. A suíte usa uma API Gmail simulada e não precisa de credenciais OAuth nem de uma caixa de entrada real. Para verificações manuais, use uma caixa de testes dedicada e nunca inclua credenciais, refresh tokens, OTPs ou conteúdo privado de mensagens em issues ou logs.
