test(B193): e2e robustos — cards ancorados pelo link exato do nome e C106 com timestamps determinísticos

- '?q=' casa prefixos de nome ('Coribe' também retorna 'São Félix do Coribe'):
  os cards B193 são ancorados por has:{ link do nome exato }.
- C106: os 8 updates seedados podiam compartilhar o mesmo now() de transação,
  tornando o sort -createdAt instável (flake '#8 no topo'); createdAt
  explícito e crescente.
This commit is contained in:
Francisco Solla 2026-08-10 10:10:20 -03:00
parent b210939226
commit 5d38bed12f
2 changed files with 17 additions and 12 deletions

View file

@ -981,11 +981,11 @@ test.describe('Municípios — card denso mobile (B193)', () => {
await page.goto(
`${campaign.baseURL}/campanha/municipios?q=${encodeURIComponent(municipality.name)}`,
)
// `?q=` matches name PREFIXES ("São Félix" also returns "São Félix do
// Coribe"), so the card is anchored on the municipality's own name.
// `?q=` matches name PREFIXES ("Coribe" also returns "São Félix do
// Coribe"), so the card is anchored on the municipality's own name link.
const card = page
.locator('[data-view="mobile-cards"] article')
.filter({ hasText: municipality.name })
.filter({ has: page.getByRole('link', { name: municipality.name, exact: true }) })
.first()
await expect(card).toBeVisible()
@ -1022,11 +1022,11 @@ test.describe('Municípios — card denso mobile (B193)', () => {
await page.goto(
`${campaign.baseURL}/campanha/municipios?q=${encodeURIComponent(municipality.name)}`,
)
// `?q=` matches name PREFIXES ("São Félix" also returns "São Félix do
// Coribe"), so the card is anchored on the municipality's own name.
// `?q=` matches name PREFIXES ("Coribe" also returns "São Félix do
// Coribe"), so the card is anchored on the municipality's own name link.
const card = page
.locator('[data-view="mobile-cards"] article')
.filter({ hasText: municipality.name })
.filter({ has: page.getByRole('link', { name: municipality.name, exact: true }) })
.first()
await expect(card).toBeVisible()
@ -1056,11 +1056,11 @@ test.describe('Municípios — card denso mobile (B193)', () => {
await page.goto(
`${campaign.baseURL}/campanha/municipios?q=${encodeURIComponent(municipality.name)}`,
)
// `?q=` matches name PREFIXES ("São Félix" also returns "São Félix do
// Coribe"), so the card is anchored on the municipality's own name.
// `?q=` matches name PREFIXES ("Coribe" also returns "São Félix do
// Coribe"), so the card is anchored on the municipality's own name link.
const card = page
.locator('[data-view="mobile-cards"] article')
.filter({ hasText: municipality.name })
.filter({ has: page.getByRole('link', { name: municipality.name, exact: true }) })
.first()
await expect(card).toBeVisible()
@ -1094,10 +1094,10 @@ test.describe('Municípios — card denso mobile (B193)', () => {
await page.goto(
`${campaign.baseURL}/campanha/municipios?q=${encodeURIComponent(withUpdate.name)}`,
)
// `?q=` matches name prefixes — anchor on the municipality's own name.
// `?q=` matches name prefixes — anchor on the municipality's own name link.
const card = page
.locator('[data-view="mobile-cards"] article')
.filter({ hasText: withUpdate.name })
.filter({ has: page.getByRole('link', { name: withUpdate.name, exact: true }) })
.first()
await expect(card).toBeVisible()
@ -1124,7 +1124,7 @@ test.describe('Municípios — card denso mobile (B193)', () => {
await page.goto(`${campaign.baseURL}/campanha/municipios?q=${encodeURIComponent(empty.name)}`)
const emptyCard = page
.locator('[data-view="mobile-cards"] article')
.filter({ hasText: empty.name })
.filter({ has: page.getByRole('link', { name: empty.name, exact: true }) })
.first()
await expect(emptyCard).toBeVisible()
await expect(emptyCard.getByRole('button', { name: /Última atualização/ })).toHaveCount(0)

View file

@ -24,6 +24,10 @@ const seedUpdates = async (
const { fixtures } = campaign
const coordinator = await fixtures.createCampaignUser('coordinator')
const municipality = await fixtures.claimMunicipality()
// Explicitly increasing timestamps: rows created back-to-back can share the
// same Postgres `now()` (transaction-scoped), which makes the feed's
// `sort: -createdAt` unstable and the "#8 on top" assertion flaky.
const base = Date.now()
for (let i = 0; i < 8; i += 1) {
await fixtures.payload.create({
collection: 'municipalityUpdate',
@ -32,6 +36,7 @@ const seedUpdates = async (
author: coordinator.id,
polarity: i % 2 === 0 ? 'boa' : 'ruim',
body: `Fato de campo C106 #${i + 1} em ${municipality.name}`,
createdAt: new Date(base + (i + 1) * 1000).toISOString(),
},
depth: 0,
})