Skip to content

Commit

Permalink
chore: Split e2e and playground (#390)
Browse files Browse the repository at this point in the history
* chore: Split e2e and playground

* chore: Remove unused file

* chore: Fix Turbo config

* chore: Trying to make Vercel happy

* chore: Testing multiple versions of Next.js in CI

* chore: Testing with canary

* chore: Disable continue-on-error

* chore: Better name on Slack

* chore: Testing better job names

* chore: Remove /e2e/ prefix on test bench

* chore: Add tests for basePath

* chore: Fix basePath

* chore: Reverse logic

* chore: Fix inclusion
  • Loading branch information
franky47 authored Nov 9, 2023
1 parent 5ad750c commit d76117e
Show file tree
Hide file tree
Showing 39 changed files with 411 additions and 128 deletions.
23 changes: 17 additions & 6 deletions .github/workflows/ci-cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,19 @@ env:

jobs:
ci:
name: Integration
name: Integration (Next.js ${{ matrix.next-version }}${{ matrix.base-path != '/' && ' with basePath' || ''}})
runs-on: ubuntu-latest
strategy:
matrix:
base-path: ['/']
next-version:
- '13.4'
- '13.5'
- '14'
- latest
include:
- next-version: 'latest'
base-path: '/base'
steps:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
- uses: pnpm/action-setup@d882d12c64e032187b2edb46d3a0d003b7a43598
Expand All @@ -23,19 +34,20 @@ jobs:
cache: pnpm
- name: Install dependencies
run: pnpm install
- name: Install Next.js version ${{ matrix.next-version }}
run: pnpm add --filter e2e next@${{ matrix.next-version }}
- name: Run integration tests
run: pnpm run ci
run: pnpm run test
env:
BASE_PATH: ${{ matrix.base-path }}
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
# - uses: coverallsapp/github-action@3dfc5567390f6fa9267c0ee9c251e4c8c3f18949
# name: Report code coverage
# continue-on-error: true
- uses: 47ng/actions-slack-notify@main
name: Notify on Slack
if: always()
with:
status: ${{ job.status }}
jobName: next@${{ matrix.next-version }}
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}

Expand Down Expand Up @@ -65,4 +77,3 @@ jobs:
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
SCEAU_PRIVATE_KEY: ${{ secrets.SCEAU_PRIVATE_KEY }}
4 changes: 2 additions & 2 deletions .github/workflows/test-against-nextjs-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ jobs:
- name: Install dependencies
run: pnpm install
- name: Install Next.js version ${{ inputs.version }}
run: pnpm add --filter next-usequerystate-playground next@${{ inputs.version }}
run: pnpm add --filter e2e next@${{ inputs.version }}
- name: Run integration tests
run: pnpm run ci
run: pnpm run test
env:
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
Expand Down
10 changes: 5 additions & 5 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,21 @@ First off, thanks for your help!
This monorepo contains:

- The source code for the `next-usequerystate` NPM package, in [`packages/next-usequerystate`](./packages/next-usequerystate).
- A Next.js app under [`packages/playground`](./packages/playground) that serves as:
- A playground deployed at <https://next-usequerystate.vercel.app>
- A host for [end-to-end tests](./packages/playground/cypress//e2e) driven by Cypress
- A Next.js app under [`packages/playground`](./packages/playground) that serves as a playground deployed at <https://next-usequerystate.vercel.app>
- A test bench for [end-to-end tests](./packages/e2e) driven by Cypress

When running `next dev`, this will:

- Build the library and watch for changes using [`tsup`](https://tsup.egoist.dev/)
- Start the playground, which will be available at <http://localhost:3000>.
- Start the end-to-end test bench, which will be available at <http://localhost:3001>.

## Testing

You can run the complete integration test suite with `pnpm run ci`.
You can run the complete integration test suite with `pnpm test`.

It will build the library, run unit tests and typing tests against it, and then
run the end-to-end tests against the playground (which uses the built library).
run the end-to-end tests against the test bench Next.js app (which uses the built library).

When proposing changes or showcasing a bug, adding a minimal reproduction in the
playground can be very helpful.
Expand Down
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
"dev": "FORCE_COLOR=3 turbo run dev",
"build": "FORCE_COLOR=3 turbo run build",
"test": "FORCE_COLOR=3 turbo run test",
"ci": "FORCE_COLOR=3 turbo run build test",
"prepare": "husky install"
},
"devDependencies": {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { defineConfig } from 'cypress'

const basePath = process.env.BASE_PATH === '/' ? '' : process.env.BASE_PATH

export default defineConfig({
e2e: {
baseUrl: `http://localhost:3000`,
baseUrl: `http://localhost:3001${basePath}`,
video: false,
fixturesFolder: false,
supportFile: false,
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

it('Reproduction for issue #388', () => {
cy.config('retries', 0)
cy.visit('/e2e/app/repro-388')
cy.visit('/app/repro-388')
cy.contains('#hydration-marker', 'hydrated').should('be.hidden')

cy.get('#start').click()
Expand All @@ -18,7 +18,7 @@ it('Reproduction for issue #388', () => {
cy.get('#counter').should('have.text', 'Counter: 1')

// Reset the page
cy.visit('/e2e/app/repro-388')
cy.visit('/app/repro-388')
cy.get('#start').click()
// The URL should have a ?counter=1 query string
cy.location('search').should('eq', '?counter=1')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,24 +87,24 @@ function runTest() {

describe('useQueryState (app router)', () => {
it('works in standard routes', () => {
cy.visit('/e2e/app/useQueryState')
cy.visit('/app/useQueryState')
runTest()
})

it('works in dynamic routes', () => {
cy.visit('/e2e/app/useQueryState/dynamic/route')
cy.visit('/app/useQueryState/dynamic/route')
runTest()
})
})

describe('useQueryState (pages router)', () => {
it('works in standard routes', () => {
cy.visit('/e2e/pages/useQueryState')
cy.visit('/pages/useQueryState')
runTest()
})

it('works in dynamic routes', () => {
cy.visit('/e2e/pages/useQueryState/dynamic/route')
cy.visit('/pages/useQueryState/dynamic/route')
runTest()
})
})
Original file line number Diff line number Diff line change
Expand Up @@ -77,24 +77,24 @@ function runTest() {

describe('useQueryStates (app router)', () => {
it('uses string by default', () => {
cy.visit('/e2e/app/useQueryStates')
cy.visit('/app/useQueryStates')
runTest()
})

it('should work with dynamic routes', () => {
cy.visit('/e2e/app/useQueryStates/dynamic/route')
cy.visit('/app/useQueryStates/dynamic/route')
runTest()
})
})

describe('useQueryStates (pages router)', () => {
it('uses string by default', () => {
cy.visit('/e2e/pages/useQueryStates')
cy.visit('/pages/useQueryStates')
runTest()
})

it('should work with dynamic routes', () => {
cy.visit('/e2e/pages/useQueryStates/dynamic/route')
cy.visit('/pages/useQueryStates/dynamic/route')
runTest()
})
})
6 changes: 6 additions & 0 deletions packages/e2e/next-env.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/// <reference types="next" />
/// <reference types="next/image-types/global" />
/// <reference types="next/navigation-types/compat/navigation" />

// NOTE: This file should not be edited
// see https://nextjs.org/docs/basic-features/typescript for more information.
6 changes: 6 additions & 0 deletions packages/e2e/next.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/** @type {import('next').NextConfig } */
const config = {
basePath: process.env.BASE_PATH === '/' ? undefined : process.env.BASE_PATH
}

export default config
37 changes: 37 additions & 0 deletions packages/e2e/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{
"name": "e2e",
"version": "0.0.0-internal",
"description": "End-to-end test bench for next-usequerystate",
"license": "MIT",
"private": true,
"author": {
"name": "François Best",
"email": "[email protected]",
"url": "https://francoisbest.com"
},
"type": "module",
"scripts": {
"dev": "next dev --port 3001",
"build": "next build",
"start": "next start --port 3001",
"pretest": "cypress install",
"test": "run-p --race start cypress:run",
"cypress:open": "cypress open",
"cypress:run": "cypress run --headless"
},
"dependencies": {
"next": "14.0.2-canary.7",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"next-usequerystate": "workspace:*"
},
"devDependencies": {
"@types/node": "^20.8.9",
"@types/react": "^18.2.33",
"@types/react-dom": "^18.2.14",
"@types/webpack": "^5.28.4",
"cypress": "^13.3.3",
"npm-run-all": "^4.1.5",
"typescript": "^5.2.2"
}
}
Original file line number Diff line number Diff line change
@@ -1,21 +1,30 @@
'use client'

import { parseAsInteger, useQueryState } from 'next-usequerystate'
import { PrefetchKind } from 'next/dist/client/components/router-reducer/router-reducer-types'
import Link from 'next/link'
import { useRouter } from 'next/navigation'
import React from 'react'

export default function Page() {
const router = useRouter()
const [counter, setCounter] = useQueryState(
'counter',
parseAsInteger.withDefault(0)
)
const [mounted, setMounted] = React.useState(false)
const manualPrefetch = React.useCallback(() => {
router.prefetch('/', { kind: PrefetchKind.FULL })
}, [router])

return (
<>
<button id="start" onClick={() => setCounter(1)}>
Start
</button>
<button id="start" onClick={() => manualPrefetch()}>
Manual prefetch
</button>
<>
<p>
The counter is set but only in the History API, the Next.js router
Expand All @@ -42,7 +51,7 @@ export default function Page() {
</Link>
{mounted && (
<Link
href="/e2e/app/useQueryState"
href="/app/useQueryState"
style={{
display: 'inline-block',
paddingInline: '1rem',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export const RoutingTourView: React.FC<RoutingTourViewProps> = ({
return (
<>
<Link
href={`/e2e/app/routing-tour/${nextPage}?from=${thisPage}&counter=${
href={`/app/routing-tour/${nextPage}?from=${thisPage}&counter=${
counter + 1
}`}
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,22 @@ export default function ServerStartPage() {
return (
<ul>
<li>
<Link href="/e2e/app/routing-tour/a?from=start.client">
<Link href="/app/routing-tour/a?from=start.client">
a (server, prefetch)
</Link>
</li>
<li>
<Link href="/e2e/app/routing-tour/b?from=start.client" prefetch={false}>
<Link href="/app/routing-tour/b?from=start.client" prefetch={false}>
b (server, no prefetch)
</Link>
</li>
<li>
<Link href="/e2e/app/routing-tour/c?from=start.client">
<Link href="/app/routing-tour/c?from=start.client">
c (client, prefetch)
</Link>
</li>
<li>
<Link href="/e2e/app/routing-tour/d?from=start.client" prefetch={false}>
<Link href="/app/routing-tour/d?from=start.client" prefetch={false}>
d (client, no prefetch)
</Link>
</li>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,22 @@ export default function ServerStartPage() {
return (
<ul>
<li>
<Link href="/e2e/app/routing-tour/a?from=start.server">
<Link href="/app/routing-tour/a?from=start.server">
a (server, prefetch)
</Link>
</li>
<li>
<Link href="/e2e/app/routing-tour/b?from=start.server" prefetch={false}>
<Link href="/app/routing-tour/b?from=start.server" prefetch={false}>
b (server, no prefetch)
</Link>
</li>
<li>
<Link href="/e2e/app/routing-tour/c?from=start.server">
<Link href="/app/routing-tour/c?from=start.server">
c (client, prefetch)
</Link>
</li>
<li>
<Link href="/e2e/app/routing-tour/d?from=start.server" prefetch={false}>
<Link href="/app/routing-tour/d?from=start.server" prefetch={false}>
d (client, no prefetch)
</Link>
</li>
Expand Down
25 changes: 25 additions & 0 deletions packages/e2e/src/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import React, { Suspense } from 'react'
import { HydrationMarker } from '../components/hydration-marker'

export const metadata = {
title: 'next-usequerystate playground',
description:
'useQueryState hook for Next.js - Like React.useState, but stored in the URL query string'
}

export default function RootLayout({
children
}: {
children: React.ReactNode
}) {
return (
<html>
<body>
<Suspense>
<HydrationMarker />
</Suspense>
{children}
</body>
</html>
)
}
Loading

0 comments on commit d76117e

Please sign in to comment.