Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .github/workflows/browser.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
15 changes: 15 additions & 0 deletions playwright.website.config.ts
Original file line number Diff line number Diff line change
@@ -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,
},
})
84 changes: 84 additions & 0 deletions test/browser/website/support-cta.spec.ts
Original file line number Diff line number Diff line change
@@ -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'),
})
})
}
21 changes: 21 additions & 0 deletions website/src/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,27 @@ function Website() {
</section>
</div>

<section className="support-cta" aria-labelledby="support-heading">
<div className="support-cta__copy">
<h2 id="support-heading">Useful in your project?</h2>
<p>
If React Swipe Actions helps you build, a GitHub star supports the
project and helps others discover it.
</p>
</div>
<div className="support-cta__actions">
<a
className="support-cta__primary"
href="https://github.com/NIPE-Solutions/react-swipe-actions"
>
Star on GitHub
</a>
<a href="https://opensource.nipesolutions.com">
Explore NIPE Open Source
</a>
</div>
</section>

<DocSection
id="anatomy"
title="Anatomy"
Expand Down
60 changes: 60 additions & 0 deletions website/src/site.css
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,7 @@ main {
}

.opening,
.support-cta,
.doc-section,
.site-footer {
inline-size: min(100% - 64px, 1120px);
Expand All @@ -222,6 +223,62 @@ main {
min-inline-size: 0;
}

.support-cta {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 24px;
padding-block: 28px;
border-block: 1px solid var(--rule);
}

.support-cta__copy {
flex: 1 1 420px;
min-inline-size: 0;
}

.support-cta h2 {
margin: 0;
font-size: 26px;
font-weight: 720;
letter-spacing: -0.03em;
line-height: 1.12;
}

.support-cta p {
max-inline-size: 60ch;
margin: 8px 0 0;
color: var(--ink-soft);
font-size: 14px;
line-height: 1.6;
}

.support-cta__actions {
display: flex;
flex-wrap: wrap;
gap: 12px;
}

.support-cta__actions a {
display: inline-flex;
align-items: center;
justify-content: center;
min-block-size: 44px;
padding: 10px 16px;
border: 1px solid var(--rule);
border-radius: 6px;
color: var(--signal-dark);
font-size: 14px;
font-weight: 690;
text-decoration: none;
}

.support-cta__actions .support-cta__primary {
border-color: var(--signal-dark);
background: var(--signal-dark);
color: var(--paper);
}

.intro {
padding-block-start: 4px;
}
Expand Down Expand Up @@ -1359,6 +1416,7 @@ kbd {
padding-inline: 18px;
}
.opening,
.support-cta,
.doc-section,
.site-footer {
inline-size: min(100% - 40px, 920px);
Expand Down Expand Up @@ -1453,6 +1511,7 @@ kbd {
white-space: nowrap;
}
.opening,
.support-cta,
.doc-section,
.site-footer {
inline-size: min(100% - 32px, 680px);
Expand Down Expand Up @@ -1510,6 +1569,7 @@ kbd {

@media (max-width: 580px) {
.opening,
.support-cta,
.doc-section,
.site-footer {
inline-size: min(100% - 24px, 520px);
Expand Down