Extrair texto de uma lista de elementos, filtrar uma resposta de API e montar conjuntos de dados de teste usam os mesmos quatro métodos do JavaScript. São eles: map, filter, find e forEach. O erro mais comum no Playwright especificamente é chamar forEach com um callback async: ele dispara promises sem aguardar, então as assertions rodam antes dos dados chegarem.
Arrays: revisão de um minuto
Um array é uma lista ordenada de valores:
const usuarios = ['Alice', 'Bob', 'Charlie'];
const precos = [12.99, 5.50, 29.00, 8.75];
const casosDeTeste = [
{ input: 'valido@email.com', devePassar: true },
{ input: 'nao-e-email', devePassar: false },
{ input: '', devePassar: false },
];Você acessa elementos pelo índice (começando em 0):
console.log(usuarios[0]); // 'Alice'
console.log(usuarios[2]); // 'Charlie'
console.log(usuarios.length); // 3Tudo o mais neste guia parte daqui.
forEach: faça algo com cada item
forEach roda uma função uma vez para cada item do array. Use quando quiser fazer algo com cada item, mas não precisar de um resultado de volta.
const usernames = ['alice', 'bob', 'charlie'];
usernames.forEach((nome) => {
console.log(`Testando usuário: ${nome}`);
});
// Saída:
// Testando usuário: alice
// Testando usuário: bob
// Testando usuário: charlieEm testes Playwright
const urlsDeLogin = [
'/pt/login',
'/en/login',
'/es/login',
];
// Verificar que todas as páginas de login por locale carregam
// (não é o padrão ideal, mas mostra o forEach em ação)
urlsDeLogin.forEach(async (url) => {
await page.goto(url);
await expect(page.locator('h1')).toBeVisible();
});map e o filter são mais adequados para esses casos.
map: transforme cada item
map cria um novo array aplicando uma função a cada item. O array original não muda.
Pense assim: "para cada item, me devolva algo diferente."
const precos = [10, 20, 30];
const comDesconto = precos.map((preco) => preco * 0.9);
console.log(comDesconto); // [9, 18, 27]
console.log(precos); // [10, 20, 30] ← inalteradoExemplo prático: extraindo texto de uma lista de elementos
Com frequência você recebe um array de locators do Playwright e precisa extrair o texto de cada um:
// Pegar todos os textos de células de uma tabela
const celulas = await page.locator('table tbody td').all();
const textos = await Promise.all(
celulas.map((celula) => celula.textContent())
);
// textos = ['Alice', '28', 'Admin', 'Bob', '34', 'User', ...]Montando dados de teste com map
const ids = [1, 2, 3, 4, 5];
const usuariosDeTeste = ids.map((id) => ({
id,
username: `user_${id}`,
email: `user${id}@teste.com`,
role: id === 1 ? 'admin' : 'member',
}));
/*
[
{ id: 1, username: 'user_1', email: 'user1@teste.com', role: 'admin' },
{ id: 2, username: 'user_2', email: 'user2@teste.com', role: 'member' },
...
]
*/Transformando dados de resposta de API
// API retorna dados brutos
const usuariosApi = [
{ first_name: 'Alice', last_name: 'Silva', is_active: 1 },
{ first_name: 'Bob', last_name: 'Santos', is_active: 0 },
];
// Transformar para o que a UI exibe
const usuariosExibidos = usuariosApi.map((u) => ({
nome: `${u.first_name} ${u.last_name}`,
ativo: u.is_active === 1,
}));
// [{ nome: 'Alice Silva', ativo: true }, { nome: 'Bob Santos', ativo: false }]filter: fique só com o que você precisa
filter cria um novo array contendo apenas os itens que passam em um teste. Os que reprovam são descartados.
const precos = [5, 12, 3, 25, 8, 40, 1];
const caros = precos.filter((preco) => preco > 10);
console.log(caros); // [12, 25, 40]
console.log(precos); // [5, 12, 3, 25, 8, 40, 1] ← inalteradoFiltrando casos de teste
É aqui que filter brilha na automação. Com uma lista grande de casos de teste, você pode dividi-los:
const todosCasos = [
{ input: 'valido@email.com', devePassar: true },
{ input: 'outro@teste.org', devePassar: true },
{ input: 'nao-e-email', devePassar: false },
{ input: '', devePassar: false },
{ input: 'faltando@', devePassar: false },
];
const casosValidos = todosCasos.filter((tc) => tc.devePassar);
const casosInvalidos = todosCasos.filter((tc) => !tc.devePassar);
// casosValidos tem 2 itens, casosInvalidos tem 3Filtrando resultados de API
// Todos os pedidos da API
const pedidos = [
{ id: 1, status: 'concluido', valor: 99 },
{ id: 2, status: 'pendente', valor: 45 },
{ id: 3, status: 'concluido', valor: 12 },
{ id: 4, status: 'cancelado', valor: 75 },
];
// Manter apenas pedidos concluídos para verificação
const pedidosConcluidos = pedidos.filter((p) => p.status === 'concluido');
// [{ id: 1, ... }, { id: 3, ... }]Filtrando elementos da página por texto
// Todas as linhas de uma tabela
const linhas = await page.locator('table tbody tr').all();
// Apenas linhas que contêm 'Admin'
const linhasAdmin = [];
for (const linha of linhas) {
const texto = await linha.textContent();
if (texto?.includes('Admin')) {
linhasAdmin.push(linha);
}
}find: pegue o primeiro que corresponde
find retorna o primeiro item que passa em um teste. Se nada corresponder, retorna undefined. Ao contrário de filter, para de buscar assim que encontra uma correspondência.
const usuarios = [
{ id: 1, nome: 'Alice', role: 'admin' },
{ id: 2, nome: 'Bob', role: 'member' },
{ id: 3, nome: 'Carol', role: 'admin' },
];
const primeiroAdmin = usuarios.find((u) => u.role === 'admin');
// { id: 1, nome: 'Alice', role: 'admin' }
const usuarioAusente = usuarios.find((u) => u.nome === 'Dave');
// undefinedEncontrando dados de teste por ID
const produtos = [
{ id: 'PROD-001', nome: 'Notebook', preco: 999 },
{ id: 'PROD-002', nome: 'Mouse', preco: 29 },
{ id: 'PROD-003', nome: 'Mesa', preco: 349 },
];
const produtoAlvo = produtos.find((p) => p.id === 'PROD-002');
// { id: 'PROD-002', nome: 'Mouse', preco: 29 }Sempre verifique se não é undefined
const produto = produtos.find((p) => p.id === 'PROD-999');
if (!produto) {
throw new Error('Dado de teste não encontrado: PROD-999');
}
// Agora é seguro usar produto
await page.fill('[data-testid="busca"]', produto.nome);filter.
Combinando os métodos
O poder real vem de encadeá-los:
const pedidosApi = [
{ id: 1, usuario: 'alice', status: 'concluido', valor: 150, itens: 3 },
{ id: 2, usuario: 'bob', status: 'pendente', valor: 50, itens: 1 },
{ id: 3, usuario: 'alice', status: 'concluido', valor: 200, itens: 5 },
{ id: 4, usuario: 'carol', status: 'cancelado', valor: 75, itens: 2 },
{ id: 5, usuario: 'alice', status: 'pendente', valor: 30, itens: 1 },
];
// Total dos pedidos concluídos da Alice
const totalAliceConcluido = pedidosApi
.filter((p) => p.usuario === 'alice' && p.status === 'concluido')
.map((p) => p.valor)
.reduce((soma, valor) => soma + valor, 0);
// 150 + 200 = 350Ou para verificação:
// Verificar que todos os preços de produto visíveis são maiores que zero
const locatorsPreco = await page.locator('[data-testid="preco-produto"]').all();
const precos = await Promise.all(
locatorsPreco.map(async (el) => {
const texto = await el.textContent();
return parseFloat(texto?.replace('R$', '').replace(',', '.').trim() ?? '0');
})
);
const temPrecoNegativo = precos.some((p) => p <= 0);
expect(temPrecoNegativo).toBe(false);Referência rápida
| Método | O que retorna | Use quando |
|--------|--------------|------------|
| forEach | Nada (undefined) | Quer efeitos colaterais (logging, ações) |
| map | Novo array, mesmo tamanho | Quer transformar cada item |
| filter | Novo array, menor ou igual | Quer um subconjunto de itens |
| find | Um item ou undefined | Quer a primeira correspondência |
Erros comuns
Usarmap quando quer forEach:
// Errado — map é para retornar valores, não efeitos colaterais
usuarios.map((usuario) => {
console.log(usuario.nome); // funciona, mas é desperdício
});
// Correto
usuarios.forEach((usuario) => {
console.log(usuario.nome);
});find pode retornar undefined:
// Isso vai lançar erro se o usuário não for encontrado
const usuario = usuarios.find((u) => u.id === 99);
usuario.nome; // TypeError: Cannot read properties of undefinedmap:
Se você fizer usuarios.map((u) => { u.role = 'admin'; return u; }), está mutando os objetos originais, não criando novos. Crie objetos novos:
// Correto — cria novos objetos
usuarios.map((u) => ({ ...u, role: 'admin' }));Nota sobre async no Playwright
Quando o callback é async (o que acontece constantemente no Playwright), use Promise.all:
// Não funciona — forEach ignora promises
celulas.forEach(async (celula) => {
const texto = await celula.textContent(); // dispara e esquece
});
// Funciona — aguarda todas as promises
const textos = await Promise.all(
celulas.map(async (celula) => await celula.textContent())
);Esse é o erro de "async em arrays" mais comum no Playwright. Na dúvida, use Promise.all com map.
Com isso, você tem os métodos de array mais usados em suites Playwright reais. map, filter, find e forEach cobrem 90% do que você vai precisar ao trabalhar com dados de teste, respostas de API e arrays de elementos de página.