Autenticação via API com Playwright

Nos artigos anteriores, abordamos dois aspectos essenciais para quem utiliza o Playwright em testes automatizados. No primeiro artigo, focamos em como configurar a pipeline do Azure para rodar os testes, facilitando a integração contínua e garantindo que os testes sejam executados automaticamente a cada nova alteração no código. No segundo, vimos como gerar código de teste utilizando o gerador do Playwright, uma ferramenta poderosa que permite criar testes de forma rápida e eficiente.

Agora, vamos avançar para outro tema importante, a autenticação via API. Este é um recurso fundamental para otimizar a execução dos testes, permitindo realizar logins diretamente pela API e evitar a repetição do processo de login via interface gráfica. Com isso, seus testes ficam mais rápidos e robustos.

A autenticação via API traz diversas vantagens quando comparada ao login via interface gráfica. Em primeiro lugar, ela reduz o tempo de execução dos testes, já que você não precisa simular o preenchimento de formulários de login e aguardar a resposta da UI. Além disso, essa abordagem é mais confiável, uma vez que minimiza falhas ligadas a elementos da interface, como mudanças no layout ou carregamento lento de páginas.

A autenticação via API é particularmente útil quando você precisa rodar uma série de testes em sequência, já que o token de acesso pode ser reutilizado em vários testes, eliminando a necessidade de logar repetidamente.

Essa técnica se mostra especialmente eficaz em cenários onde o foco é testar funcionalidades após o login, permitindo que você pule a etapa de autenticação via interface gráfica e vá direto ao que interessa: os testes das funcionalidades principais.

Agora que já entendemos a importância da autenticação via API, vamos ver um exemplo prático de como implementá-la utilizando o Playwright. O código a seguir mostra como fazer uma requisição de login via API e como configurar os tokens de acesso e refresh como cookies, permitindo que eles sejam reutilizados nos testes.

async function authenticate() {
    const payload = {
        // Defina corretamente as propriedades necessárias para a autenticação.
        // Neste caso, o email e a senha são os dados que serão enviados na requisição.
        email: "usuario@admin.com",   
        password: "minhaSenhaSecreta123"
    }

    // Lembre-se de substituir a URL abaixo pela URL de autenticação da sua aplicação.
    const response = await this.request.post(`https://urldosistema.com/authenticate`, {
        headers: {
            "Content-Type": "application/json", // O conteúdo enviado será em formato JSON.
        },
        data: payload  // O payload com as credenciais é enviado no corpo da requisição.
    });

    const status = await response.status();
    // Aqui verificamos se o status da resposta é 200, o que indica sucesso na autenticação.
    await expect(status).toBe(200);

    const responseBody = await response.json();

    // Extraímos os tokens de autenticação da resposta da API.
    // Verifique como a sua aplicação retorna esses tokens e ajuste os nomes das propriedades se necessário.
    const accessToken: string = responseBody.accesstoken; 
    const refreshToken: string = responseBody.refreshtoken;

    // Agora, vamos criar cookies para armazenar esses tokens, 
    // facilitando a reutilização deles em outros testes.
    const cookies = [
        {
            name: "access_token",  // Nome do cookie para o token de acesso.
            value: accessToken,    // Valor do token de acesso obtido.
            domain: "dominioDoSistema", // Substitua pelo domínio do seu sistema.
            path: "/",  
            expires: Math.floor(Date.now() / 1000) + 3600, // O cookie expira em 1 hora.
            httpOnly: false,  
            secure: true,     /
            sameSite: "Strict" 
        },
        {
            name: "refresh_token",  // Nome do cookie para o token de refresh.
            value: refreshToken,    // Valor do token de refresh obtido.
            domain: "dominioDoSistema", // Substitua pelo domínio do seu sistema.
            path: "/",
            expires: Math.floor(Date.now() / 1000) + 3600 * 24 * 30, // O cookie expira em 30 dias.
            httpOnly: true,
            secure: true,
            sameSite: "Strict"
        }
    ];

    // Caso o status da requisição seja 200 (sucesso na autenticação),
    // salvamos os cookies em um arquivo JSON para serem reutilizados em testes subsequentes.
    // Certifique-se de ajustar o nome do arquivo conforme sua necessidade.
    if (status === 200) {
        const filePath = `./.auth/ADMIN.json`;
        fs.writeFileSync(filePath, JSON.stringify({ cookies }, null, 2));  // Salvando os cookies no arquivo.
    }

    return cookies;  // Retornando os cookies.
}

Dica Extra: Gerando o Modelo de Cookies Automaticamente

Caso você não saiba como estruturar a variável cookies, uma alternativa eficiente é realizar o login via UI utilizando o Playwright e capturar os cookies automaticamente. Dessa forma, você pode obter o modelo exato de como os dados devem ser salvos.

Para isso, basta seguir os seguintes passos:

  1. Execute o fluxo de login na interface do usuário (UI) usando o Playwright.
  2. Após o login bem-sucedido, utilize o seguinte comando para salvar os cookies em um arquivo:
await page.context().storageState({ path: './.auth/ADMIN.json'});

Esse código vai gerar um arquivo JSON com os cookies, tokens de autenticação e outras informações de estado de armazenamento do navegador. Assim, você pode usar esse arquivo como referência para estruturar a variável cookies adequadamente nos seus testes automatizados.

Com isso podemos acessar os cookies e realizar o login de duas formas:

1. Utilizando o arquivo gerado pela função authenticate com o comando test.use()

Você pode utilizar o arquivo de cookies gerado pela função authenticate diretamente nos seus testes, utilizando o comando test.use() do Playwright. Esse comando permite configurar o estado de armazenamento (incluindo cookies e tokens) antes de rodar os testes.

No exemplo abaixo, usamos o arquivo ./.auth/ADMIN.json gerado na autenticação para acessar uma conta:

test.use({ storageState: './.auth/ADMIN.json' });

// Dentro da sua spec:
test('Acessar a conta com cookies armazenados', async ({ page }) => {
    await page.goto('/'); // Navegue até a URL da sua aplicação já autenticado.
    // Realize suas verificações ou ações aqui
});

Esse método é rápido e eficiente, pois evita que você precise realizar o processo de autenticação a cada execução dos testes, reutilizando o estado salvo.

OBS.: Neste caso é necessário que a função authenticate seja executada em outra spec para que o arquivo seja gerado. Recomendo que tenha uma spec setup de login, realizando a autenticação nas contas que irá utilizar ao decorrer dos testes.


2. Executando o comando authenticate e gravando os cookies diretamente no navegador

A segunda maneira de utilizar os cookies é executando a função authenticate em tempo de execução e adicionando os cookies diretamente ao contexto do navegador. Assim, você pode autenticar-se e carregar os cookies no navegador da seguinte maneira:

test.beforeEach( async ({page, request}) => {
  await page.goto('/'); // Primeiro, navegue até a página da sua aplicação.
  // Autentica e gera os cookies.
  const cookies = await authenticate(); 
  // Adiciona os cookies ao contexto do navegador.
  await page.context().addCookies(cookies); 
  // A partir daqui, você está autenticado e pode realizar ações como usuário logado.
}

Esse método é útil caso você prefira realizar a autenticação em tempo real, em vez de reutilizar um arquivo de estado salvo.


Ambas as abordagens são válidas e podem ser utilizadas conforme a necessidade do seu cenário de teste. Se você quiser otimizar o tempo dos testes, a primeira abordagem é ideal, pois evita realizar o login a cada execução. A segunda abordagem é mais flexível para cenários onde a autenticação deve ocorrer durante o teste

Seja o primeiro a comentar

Faça um comentário

Seu e-mail não será divulgado.


*