slimcore-website/e2e/smoke.spec.ts

97 lines
4.1 KiB
TypeScript
Raw Permalink Normal View History

import { test, expect } from '@playwright/test';
const routes = [
{ path: '/', lang: 'de', h1Contains: 'Schlank starten' },
{ path: '/module', lang: 'de', h1Contains: 'Module' },
{ path: '/tester', lang: 'de', h1Contains: 'Lücken' },
{ path: '/souveraenitaet', lang: 'de', h1Contains: 'Ihre Daten' },
{ path: '/roadmap', lang: 'de', h1Contains: 'Heute' },
{ path: '/kontakt', lang: 'de', h1Contains: 'erreichen' },
{ path: '/impressum', lang: 'de', h1Contains: 'Impressum' },
{ path: '/datenschutz', lang: 'de', h1Contains: 'Datenschutz' },
{ path: '/en/', lang: 'en', h1Contains: 'Start lean' },
{ path: '/en/module', lang: 'en', h1Contains: 'Modules' },
{ path: '/en/tester', lang: 'en', h1Contains: 'gaps' },
{ path: '/en/sovereignty', lang: 'en', h1Contains: 'Your data' },
{ path: '/en/roadmap', lang: 'en', h1Contains: 'Today' },
{ path: '/en/contact', lang: 'en', h1Contains: 'reach' },
{ path: '/en/imprint', lang: 'en', h1Contains: 'Imprint' },
{ path: '/en/privacy', lang: 'en', h1Contains: 'Privacy' },
];
test.describe('All routes return 200 with correct lang and headline', () => {
for (const r of routes) {
test(`${r.path} renders`, async ({ page }) => {
const response = await page.goto(r.path);
expect(response?.status()).toBe(200);
await expect(page.locator('html')).toHaveAttribute('lang', r.lang);
await expect(page.locator('h1')).toContainText(r.h1Contains);
await expect(page.locator('#nav-bar a[href="/"], #nav-bar a[href="/en/"]').first()).toContainText('SlimCore');
});
}
});
test.describe('NavBar dual-mode toggles on dark-hero pages', () => {
test('Home dark hero: nav dark at top, light after scroll past hero', async ({ page }) => {
await page.goto('/');
await page.waitForFunction(() => document.getElementById('nav-bar')?.dataset.mode === 'dark');
await page.evaluate(() => window.scrollTo(0, 2000));
await page.waitForFunction(() => document.getElementById('nav-bar')?.dataset.mode === 'light');
});
test('Module page also has dark hero', async ({ page }) => {
await page.goto('/module');
await page.waitForFunction(() => document.getElementById('nav-bar')?.dataset.mode === 'dark');
});
});
test.describe('Module filter island', () => {
test('Filter pills hydrate and filter the list', async ({ page }) => {
await page.goto('/module');
await expect(page.locator('main ul li')).toHaveCount(19);
await page.locator('button[aria-pressed]', { hasText: /^Verfügbar$/ }).click();
await expect(page.locator('main ul li')).toHaveCount(6);
await expect(page.locator('[aria-live="polite"]')).toHaveText(/6 Module/);
});
});
test.describe('Language switcher', () => {
test('From DE home, EN button leads to /en/', async ({ page }) => {
await page.goto('/');
await page.locator('.nav-lang-link', { hasText: 'EN' }).click();
await expect(page).toHaveURL('/en/');
await expect(page.locator('html')).toHaveAttribute('lang', 'en');
});
test('From EN home, DE button leads to /', async ({ page }) => {
await page.goto('/en/');
await page.locator('.nav-lang-link', { hasText: 'DE' }).click();
await expect(page).toHaveURL('/');
await expect(page.locator('html')).toHaveAttribute('lang', 'de');
});
});
test.describe('Footer + sitemap + robots', () => {
test('Sitemap-index exists and links to slimcore.io', async ({ request }) => {
const res = await request.get('/sitemap-index.xml');
expect(res.status()).toBe(200);
const body = await res.text();
expect(body).toContain('https://slimcore.io/sitemap-0.xml');
});
test('robots.txt exists and disallows /dev/', async ({ request }) => {
const res = await request.get('/robots.txt');
expect(res.status()).toBe(200);
const body = await res.text();
expect(body).toContain('Disallow: /dev/');
expect(body).toContain('Sitemap: https://slimcore.io/sitemap-index.xml');
});
test('Footer Impressum link works', async ({ page }) => {
await page.goto('/');
await page.locator('footer a[href="/impressum"]').click();
await expect(page).toHaveURL('/impressum');
await expect(page.locator('h1')).toContainText('Impressum');
});
});