diff --git a/.github/workflows/browser.yml b/.github/workflows/browser.yml index dfa3075..b9f2668 100644 --- a/.github/workflows/browser.yml +++ b/.github/workflows/browser.yml @@ -40,6 +40,8 @@ jobs: run: npm run verify:website:browser - name: Test Chromium run: npm run test:e2e -- --project=chromium --reporter=line,html + - name: Test website support links + run: npx playwright test --config playwright.website.config.ts --project=chromium --reporter=line,html - name: Upload Chromium failure evidence if: failure() uses: actions/upload-artifact@v7 @@ -73,8 +75,12 @@ jobs: restore-keys: ${{ runner.os }}-playwright-firefox- - name: Install Firefox run: npx playwright install --with-deps firefox + - name: Build website + run: npm run build:website - name: Test Firefox run: npm run test:e2e -- --project=firefox --reporter=line,html + - name: Test website support links + run: npx playwright test --config playwright.website.config.ts --project=firefox --reporter=line,html - name: Upload Firefox failure evidence if: failure() uses: actions/upload-artifact@v7 @@ -108,8 +114,12 @@ jobs: restore-keys: ${{ runner.os }}-playwright-webkit- - name: Install WebKit run: npx playwright install --with-deps webkit + - name: Build website + run: npm run build:website - name: Test WebKit run: npm run test:e2e -- --project=webkit --reporter=line,html + - name: Test website support links + run: npx playwright test --config playwright.website.config.ts --project=webkit --reporter=line,html - name: Upload WebKit failure evidence if: failure() uses: actions/upload-artifact@v7 diff --git a/playwright.website.config.ts b/playwright.website.config.ts new file mode 100644 index 0000000..bf86cff --- /dev/null +++ b/playwright.website.config.ts @@ -0,0 +1,15 @@ +import { defineConfig } from '@playwright/test' + +import config from './playwright.config' + +export default defineConfig({ + ...config, + testDir: './test/browser/website', + testMatch: 'support-cta.spec.ts', + webServer: { + command: + 'npx vite preview --config website/vite.config.ts --host 127.0.0.1 --port 4173', + url: 'http://127.0.0.1:4173', + reuseExistingServer: false, + }, +}) diff --git a/test/browser/website/support-cta.spec.ts b/test/browser/website/support-cta.spec.ts new file mode 100644 index 0000000..5603eb7 --- /dev/null +++ b/test/browser/website/support-cta.spec.ts @@ -0,0 +1,84 @@ +import { expect, test } from '@playwright/test' + +for (const width of [1440, 390, 320]) { + test(`homepage support links remain usable at ${String(width)}px`, async ({ + page, + browserName, + }, testInfo) => { + await page.setViewportSize({ width, height: 900 }) + await page.goto('/') + const support = page.getByRole('region', { + name: 'Useful in your project?', + }) + await expect(support).toBeVisible() + await expect( + support.getByRole('heading', { + level: 2, + name: 'Useful in your project?', + }), + ).toBeVisible() + expect( + await support.evaluate((section) => + section.previousElementSibling?.matches('.opening'), + ), + ).toBe(true) + + const star = support.getByRole('link', { name: 'Star on GitHub' }) + const explore = support.getByRole('link', { + name: 'Explore NIPE Open Source', + }) + await expect(star).toHaveAttribute( + 'href', + 'https://github.com/NIPE-Solutions/react-swipe-actions', + ) + await expect(explore).toHaveAttribute( + 'href', + 'https://opensource.nipesolutions.com', + ) + await expect(support.locator('p')).not.toBeEmpty() + await support.scrollIntoViewIfNeeded() + for (const link of [star, explore]) { + await expect(link).toBeVisible() + const box = await link.boundingBox() + expect(box).not.toBeNull() + if (!box) throw new Error('Support link is not measurable') + expect(box.height).toBeGreaterThanOrEqual(44) + expect(box.width).toBeGreaterThanOrEqual(44) + expect(box.x).toBeGreaterThanOrEqual(0) + expect(box.x + box.width).toBeLessThanOrEqual(width) + } + expect( + await support.evaluate( + (section) => section.scrollWidth <= section.clientWidth, + ), + ).toBe(true) + + await star.focus() + const macWebKit = browserName === 'webkit' && process.platform === 'darwin' + const tab = macWebKit ? 'Alt+Tab' : 'Tab' + await page.keyboard.press(macWebKit ? 'Shift+Alt+Tab' : 'Shift+Tab') + await page.keyboard.press(tab) + await expect(star).toBeFocused() + const outline = await star.evaluate((link) => { + const style = getComputedStyle(link) + return { + width: parseFloat(style.outlineWidth), + style: style.outlineStyle, + } + }) + expect(outline.width).toBeGreaterThanOrEqual(2) + expect(outline.style).not.toBe('none') + await page.keyboard.press(tab) + await expect(explore).toBeFocused() + await expect(explore).toHaveCSS('outline-style', 'solid') + expect( + await explore.evaluate((link) => + parseFloat(getComputedStyle(link).outlineWidth), + ), + ).toBeGreaterThanOrEqual(2) + if (process.env.SUPPORT_CTA_SCREENSHOTS === '1') + await support.screenshot({ + path: testInfo.outputPath('support-cta.png'), + }) + }) +} diff --git a/website/src/main.tsx b/website/src/main.tsx index 98fcf4e..c982943 100644 --- a/website/src/main.tsx +++ b/website/src/main.tsx @@ -108,6 +108,27 @@ function Website() { +
+
+

Useful in your project?

+

+ If React Swipe Actions helps you build, a GitHub star supports the + project and helps others discover it. +

+
+
+ + Star on GitHub + + + Explore NIPE Open Source + +
+
+