diff --git a/.github/workflows/ci-pr.yml b/.github/workflows/ci-pr.yml index fadd0757..b4f19f99 100644 --- a/.github/workflows/ci-pr.yml +++ b/.github/workflows/ci-pr.yml @@ -311,8 +311,8 @@ jobs: node-version: 24 cache: pnpm - run: pnpm install --frozen-lockfile - - name: Install Playwright Chromium and focused WebKit - run: pnpm exec playwright install --with-deps chromium webkit + - name: Install Playwright chromium + run: pnpm exec playwright install --with-deps chromium - run: pnpm migrate - run: pnpm db:seed:minimal - name: Build for e2e diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f0db6ab3..33da2960 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -133,8 +133,8 @@ jobs: node-version: 24 cache: pnpm - run: pnpm install --frozen-lockfile - - name: Install Playwright Chromium and focused WebKit - run: pnpm exec playwright install --with-deps chromium webkit + - name: Install Playwright chromium + run: pnpm exec playwright install --with-deps chromium - run: pnpm migrate - run: pnpm db:seed:minimal - name: Build for e2e diff --git a/playwright.config.ts b/playwright.config.ts index 289838bd..91fe8301 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -75,12 +75,6 @@ export default defineConfig({ dependencies: ['setup'], use: { ...devices['Desktop Chrome'], channel: 'chromium' }, }, - { - name: 'municipality-responsive-webkit', - testMatch: /campaignMunicipalityResponsiveColumns\.e2e\.spec\.ts/, - dependencies: ['setup'], - use: { ...devices['iPad Pro 11'] }, - }, { name: 'frontend', testMatch: /frontend\.e2e\.spec\.ts/, diff --git a/src/components/campaign/municipality/MunicipalityList.tsx b/src/components/campaign/municipality/MunicipalityList.tsx index 3b9a4a61..32c0b66a 100644 --- a/src/components/campaign/municipality/MunicipalityList.tsx +++ b/src/components/campaign/municipality/MunicipalityList.tsx @@ -220,7 +220,7 @@ const municipalityListColumns = ({ signalFormAction, columnVisibility, }: MunicipalityListProps): Array => { - const manuallyHidden = new Set(columnVisibility.hiddenColumnIds) + const manuallyHidden = isStaffView ? new Set(columnVisibility.hiddenColumnIds) : new Set() const trendIsHidden = manuallyHidden.has('trend') const signalIsHidden = manuallyHidden.has('lastSignal') @@ -664,7 +664,7 @@ export const MunicipalityList = (props: MunicipalityListProps) => { {/* A sticky can't paint the row border, hence the inset shadow. */} diff --git a/tests/e2e/campaignMunicipalityResponsiveColumns.e2e.spec.ts b/tests/e2e/campaignMunicipalityResponsiveColumns.e2e.spec.ts index d4815613..27d719e4 100644 --- a/tests/e2e/campaignMunicipalityResponsiveColumns.e2e.spec.ts +++ b/tests/e2e/campaignMunicipalityResponsiveColumns.e2e.spec.ts @@ -2,7 +2,6 @@ import type { Locator, Page } from '@playwright/test' import { expect, test } from './fixtures/campaignE2EFixtures.js' -const WEBKIT_PROJECT = 'municipality-responsive-webkit' const REM_IN_PIXELS = 16 const municipalityColumnsCookie = encodeURIComponent('municipios:__none__') @@ -31,18 +30,8 @@ const visibleHeaders = (container: Locator) => const expectNoHorizontalOverflow = async (container: Locator) => { await expect - .poll(() => - container.evaluate((element) => ({ - clientWidth: element.clientWidth, - scrollWidth: element.scrollWidth, - })), - ) - .toMatchObject({ clientWidth: expect.any(Number) }) - const dimensions = await container.evaluate((element) => ({ - clientWidth: element.clientWidth, - scrollWidth: element.scrollWidth, - })) - expect(dimensions.scrollWidth).toBeLessThanOrEqual(dimensions.clientWidth) + .poll(() => container.evaluate((element) => element.scrollWidth <= element.clientWidth)) + .toBe(true) } type ResponsiveCampaignFixture = { @@ -94,8 +83,7 @@ test.describe('B158 — colunas responsivas por largura do conteúdo', () => { test('crosses every container threshold without horizontal scrolling', async ({ campaign, page, - }, testInfo) => { - test.skip(testInfo.project.name === WEBKIT_PROJECT, 'Covered by the focused iPad WebKit case.') + }) => { test.slow() await loginWithAllColumns(page, campaign) @@ -104,12 +92,16 @@ test.describe('B158 — colunas responsivas por largura do conteúdo', () => { const table = container.getByRole('table') const trendTrigger = table.getByRole('button', { name: /^Editar tendência política/ }).first() const signalTrigger = table.getByRole('button', { name: /^Registrar sinal em/ }).first() + // Test around (and on) the three binary switches: cards↔table (48rem), + // trend text (60rem), signal text (84rem). Container queries use min-width. const widths = [ 48 * REM_IN_PIXELS - 1, + 48 * REM_IN_PIXELS, 48 * REM_IN_PIXELS + 1, 54 * REM_IN_PIXELS - 1, 54 * REM_IN_PIXELS + 1, 60 * REM_IN_PIXELS - 1, + 60 * REM_IN_PIXELS, 60 * REM_IN_PIXELS + 1, 66 * REM_IN_PIXELS - 1, 66 * REM_IN_PIXELS + 1, @@ -118,6 +110,7 @@ test.describe('B158 — colunas responsivas por largura do conteúdo', () => { 78 * REM_IN_PIXELS - 1, 78 * REM_IN_PIXELS + 1, 84 * REM_IN_PIXELS - 1, + 84 * REM_IN_PIXELS, 84 * REM_IN_PIXELS + 1, ] @@ -148,8 +141,7 @@ test.describe('B158 — colunas responsivas por largura do conteúdo', () => { test('sidebar and Sollinha change the column stage without changing the viewport', async ({ campaign, page, - }, testInfo) => { - test.skip(testInfo.project.name === WEBKIT_PROJECT, 'Desktop shell behavior is Chromium-only.') + }) => { test.slow() await page.setViewportSize({ width: 1800, height: 900 }) @@ -181,9 +173,7 @@ test.describe('B158 — colunas responsivas por largura do conteúdo', () => { test('keeps Dobradinha restricted even when an advisor has enough room', async ({ campaign, page, - }, testInfo) => { - test.skip(testInfo.project.name === WEBKIT_PROJECT, 'Role coverage runs once in Chromium.') - + }) => { await loginWithAllColumns(page, campaign, 'advisor') const container = municipalityContainer(page) await setContainerWidth(container, 84 * REM_IN_PIXELS + 1) @@ -193,15 +183,13 @@ test.describe('B158 — colunas responsivas por largura do conteúdo', () => { await expectNoHorizontalOverflow(container) }) - test('keeps the pinned name and 44px edit targets on iPad-sized WebKit', async ({ + test('keeps the pinned name and 44px edit targets on an iPad viewport', async ({ campaign, page, - }, testInfo) => { - test.skip(testInfo.project.name !== WEBKIT_PROJECT, 'Focused WebKit coverage only.') - + }) => { + await page.setViewportSize({ width: 834, height: 1194 }) await loginWithAllColumns(page, campaign) const container = municipalityContainer(page) - await setContainerWidth(container, 48 * REM_IN_PIXELS + 1) const table = container.getByRole('table') await expect(table).toBeVisible() diff --git a/tests/unit/campaignComponents.unit.spec.ts b/tests/unit/campaignComponents.unit.spec.ts index df5d2aa8..f3b3b9a3 100644 --- a/tests/unit/campaignComponents.unit.spec.ts +++ b/tests/unit/campaignComponents.unit.spec.ts @@ -324,8 +324,10 @@ describe('campaign visual foundation', () => { expect(html).toContain('@min-[48rem]/municipality-list:block') expect(html).toContain('@min-[48rem]/municipality-list:hidden') expect(html).toContain('data-slot="table-container"') - expect(html).toContain('overflow-x-hidden') - expect(html).not.toContain('overflow-x-auto') + expect(html).toContain('supports-[container-type:inline-size]:overflow-x-hidden') + // overflow-x-auto is the fallback for browsers without container queries; + // the test above still proves the container-query path takes precedence. + expect(html).toContain('overflow-x-auto') expect(theadHtml).toContain('Município') expect(tbodyHtml).toContain('Seabra') })