Konfiguracja testów E2E w Next.js z App Router nie jest skomplikowana, ale wymaga kilku istotnych decyzji, które wpływają na cały workflow Twojego zespołu. Ten artykuł przeprowadzi Cię przez cały proces ten proces – od npm install do zielonego ✅ w GitHub Actions.
Krótka odpowiedź: Cypress w Next.js App Router skonfiguruj z cypress.config.ts, TypeScript i start-server-and-test do lokalnego uruchamiania. Skup się, by stosować fixtures do danych testowych, custom commands do eliminacji powtarzalnego kodu logowania (z cy.session() do cache'owania sesji) i data-testid selektorów odpornych na refactor w przyszłości. W CI uruchamiaj testy przeciwko zbudowanej aplikacji (next build + next start), a nie next dev - wszystko po to, by pomniejszyć różnicę między testem, a produkcją.
Krok 5: Testowanie App Router – specyficzne sprawy
Loading states i Suspense
Next.js App Router intensywnie korzysta z loading.tsx i Suspense, musisz je uwzględnić w testach:
Code
it('shows loading skeleton while fetching data', () => { cy.intercept('GET', '/api/products', (req) => { req.on('response', (res) => { res.setDelay(2000) // symuluj wolny response }) }) cy.visit('/products') // Sprawdź loading state cy.get("[data-testid='product-skeleton']").should('be.visible') // Poczekaj na dane cy.get("[data-testid='product-card']", { timeout: 5000 }).should( 'have.length.at.least', 1, ) // Loading powinien zniknąć cy.get("[data-testid='product-skeleton']").should('not.exist')})
Server Actions
Przy Server Actions nie warto przywiązywać testów do wewnętrznego transportu Next.js, ponieważ dużo stabilniejszy test sprawdza efekt widoczny dla użytkownika:
Code
it('submits form via Server Action', () => { cy.login() cy.visit('/settings') cy.get("[name='displayName']").clear().type('Nowa Nazwa') cy.get("[data-testid='save-button']").click() cy.shouldShowToast('Ustawienia zapisane') cy.contains('Nowa Nazwa').should('be.visible')})
Intercepcję zachowaj raczej do zewnętrznych usług, na przykład gdy formularz po drodze wywołuje Stripe, własne API, czyli Application Programming Interface, definiuje sposób komunikacji między aplikacjami lub modułami. partnera albo webhook.
Parallel Routes i Intercepting Routes
Code
it('opens product modal via intercepting route', () => { cy.visit('/products') cy.get("[data-testid='product-card']").first().click() // Modal powinien się otworzyć (intercepting route) cy.get("[role='dialog']").should('be.visible') cy.get("[role='dialog']").contains('Laptop ThinkPad X1') // URL się zmienił cy.url().should('include', '/products/1') // Zamknij modal cy.get("[aria-label='Zamknij']").click() cy.get("[role='dialog']").should('not.exist') cy.url().should('eq', `${Cypress.config('baseUrl')}/products`)})
W CI uruchamiaj testy przeciwko zbudowanej aplikacji (next build + next start), nie przeciwko next dev. To zmniejsza różnicę między testem a produkcją i zwykle ogranicza flaky zachowania.
// W teście:beforeEach(() => { cy.task('seedDatabase')})afterEach(() => { cy.task('cleanDatabase')})
FAQ
Dlaczego warto pisać testy E2E w Next.js?
Testy E2E weryfikują całą ścieżkę użytkownika, tj. od kliknięcia przycisku, przez żądanie HTTP, aż po zmianę widoczną w UI, czyli User Interface, to wizualna i interakcyjna warstwa produktu.. W przeciwieństwie do testów jednostkowych nie testują izolowanych funkcji, tylko faktyczne działanie aplikacji w przeglądarce. W Next.js App Router, gdzie renderowanie serwer-klient potrafi być bardziej złożone, testy E2E wychwytują błędy integracyjne, których testy jednostkowe nie obejmują.
Czym są fixtures w Cypress i kiedy ich używać?
Fixtures to statyczne pliki JSON (lub inne) z danymi testowymi, przechowywane w cypress/fixtures/ i używaj ich do mockowania odpowiedzi API (cy.intercept()), dostarczania danych wejściowych formularzy i izolowania testów od zewnętrznych zależności. Przy użyciu fixtures, test jest przewidywalny, powtarzalny i to niezależnie od stanu backendu.
Jak unikać flaky testów w Cypress?
Najważniejsze to nie używać cy.wait(ms) z hardcoded czasem, zamiast tego czekaj na aliasowany request (cy.wait('@alias')) lub używaj asercji z timeoutem. Stosuj selektory data-testid zamiast klas CSS lub tekstu, które mogą się zmieniać w przyszłości. W CI uruchamiaj testy na zbudowanej aplikacji, a nie dev serwerze (ważne!). Na koniec, włącz retries: { runMode: 2 } dla CI, żeby odfiltrować sporadyczne problemy środowiskowe.
Jak działa cy.session() i dlaczego przyspiesza testy?
cy.session() cache'uje stan sesji (cookies, localStorage, sessionStorage) po pierwszym logowaniu i przywraca go dla kolejnych testów zamiast logować się każdorazowo. W ten sposób testy, które wymagają uwierzytelnionego użytkownika, nie muszą przechodzić pełnego procesu logowania, a sesja jest zapisana i odtwarzana, co znacząco skraca czas wykonania całego zestawu testów.
Jak konfigurować zmienne środowiskowe w Cypress dla CI?
Zmienne podawaj przez env w cypress.config.ts dla wartości niepoufnych lub przez plik cypress.env.json (w .gitignore) lokalnie. W GitHub Actions używaj CYPRESS_ prefix w sekcji env workflowa, a wartości przechowuj w GitHub Secrets. Cypress automatycznie mapuje CYPRESS_FOO na Cypress.env('FOO') w testach.
Czy powinienem testować Server Actions bezpośrednio w Cypress?
Nie, przywiązywanie testów do wewnętrznego transportu Next.js (np. intercepcja fetch do Server Actions) prowadzi do destabilizacji testów, które łamią się przy zmianach frameworka. Znacznie lepszym podejściem jest testowanie efektu widocznego dla użytkownika - po prostu wypełnij formularz, potem kliknij zapisz, sprawdź czy pojawił się toast i zaktualizowana treść. Intercepcję stosuj do zewnętrznych usług (Stripe, zewnętrzne API), a nie do wewnętrznych mechanizmów Next.js.
Jak zintegrować Cypress z GitHub Actions?
Użyj oficjalnej akcji cypress-io/github-action@v6 zamiast ręcznego konfigurowania: dostarcza parametry start (komenda uruchamiająca serwer) i wait-on (URL do odczekania przed startem testów). Artefakty (screenshoty przy błędach, nagrania wideo) uploaduj przez actions/upload-artifact — screenshoty tylko if: failure(), nagrania if: always(). Dla dużych zestawów testów rozważ paralelizację przez matrix strategy.
Podsumowanie
Masz teraz gotowy kompletny setup i Cypress skonfigurowany z Next.js App Router, TypeScript, fixtures, custom commands i CI/CD to praktyka automatyzacji testów, buildów i wdrożeń w procesie dostarczania oprogramowania. na GitHub Actions. Od czego zacząć? Zacznij od jednej krytycznej ścieżki użytkownika i testuj efekt, a nie samą implementację, ponieważ lepiej mieć 5 stabilnych testów E2E uruchamianych na buildzie produkcyjnym niż 50 testów związanych z detalami transportu HTTP, które łamią się przy każdej zmianie wewnątrz frameworka.
Jeśli chcesz przełożyć ten temat na lepszą architekturę frontendu, uporządkować React lub Next.js i podnieść jakość pracy zespołu, skontaktuj się ze mną. Pomagam zamieniać wiedzę z artykułów w praktyczne decyzje technologiczne.
Maciej Sala — project manager i frontendowiec z doświadczeniem w marketingu internetowym. Na co dzień pracuję z Reactem, Next.js i TypeScriptem, łącząc perspektywę produktową z praktycznym podejściem do kodu. Przez kilka lat związany z branżą gier wideo jako project manager i game designer.
Absolwent historii na Uniwersytecie Jagiellońskim i studiów podyplomowych z marketingu internetowego na Akademii Górniczo-Hutniczej w Krakowie. Poza pracą trenuje na siłowni, maluje figurki i realizuje własne projekty.
Astro.js vs Next.js — które narzędzie wybrać w 2026 roku?
Fachowe porównanie Astro.js i Next.js z perspektywy developera pracującego na co dzień w Next.js. Architektura, wydajność, SEO, DX, koszty i konkretne use case — z benchmarkami i przykładami kodu.
WordPress → Next.js — migracja treści, redirecty 301 i zachowanie pozycji SEO
Jak przenieść stronę z WordPress na Next.js bez utraty pozycji w Google? Eksport treści, mapowanie URL, redirecty 301, migracja obrazów i weryfikacja indeksacji.
Google Search Console + Next.js — indeksacja, błędy, performance i co z nimi robić
Jak korzystać z Google Search Console dla strony Next.js? Weryfikacja, sitemap, indeksacja, Core Web Vitals, crawl budget i najczęstsze problemy — praktyczny poradnik.