Skip to content

Commit 167bc27

Browse files
authored
Merge branch 'canary' into perf/shared-static-worker-pool
2 parents decb63c + 06e08ac commit 167bc27

File tree

26 files changed

+475
-140
lines changed

26 files changed

+475
-140
lines changed

.github/workflows/build_test_deploy.yml

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,11 @@ jobs:
6060
- uses: actions/download-artifact@v2
6161
with:
6262
name: next-swc-binaries
63-
path: packages/next/native
63+
path: packages/next/build/swc/dist
64+
# Only check linux build for now, mac builds can sometimes be different even with the same code
65+
- run: |
66+
mv ./packages/next/build/swc/dist/next-swc.linux-x64-gnu.node \
67+
./packages/next/native/next-swc.linux-x64-gnu.node
6468
- run: ./scripts/check-pre-compiled.sh
6569
if: ${{needs.build.outputs.docsChange != 'docs only change'}}
6670

@@ -260,8 +264,8 @@ jobs:
260264
- uses: actions/download-artifact@v2
261265
with:
262266
name: next-swc-binaries
263-
path: packages/next/native
264-
- run: ./scripts/prepublish-native.js
267+
path: packages/next/build/swc/dist
268+
- run: ./scripts/publish-native.js $GITHUB_REF
265269
- run: ./scripts/publish-release.sh
266270

267271
releaseStats:
@@ -325,10 +329,10 @@ jobs:
325329
id: binary-cache
326330
uses: actions/cache@v2
327331
with:
328-
path: packages/next/native/**
332+
path: packages/next/native/next-swc.*.node
329333
key: next-swc-nightly-2021-03-25-${{ matrix.target }}-${{ hashFiles('packages/next/build/swc/**') }}
330334
- name: 'Build'
331-
if: steps.binary-cache.outputs.cache-hit != true
335+
if: steps.binary-cache.outputs.cache-hit != 'true'
332336
run: yarn build-native --target ${{ matrix.target }}
333337
env:
334338
MACOSX_DEPLOYMENT_TARGET: '10.13'

docs/manifest.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,10 @@
117117
"title": "Authentication",
118118
"path": "/docs/authentication.md"
119119
},
120+
{
121+
"title": "Testing",
122+
"path": "/docs/testing.md"
123+
},
120124
{
121125
"title": "Advanced Features",
122126
"routes": [

docs/testing.md

Lines changed: 335 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,335 @@
1+
# Testing
2+
3+
<details open>
4+
<summary><b>Examples</b></summary>
5+
<ul>
6+
<li><a href="https://github.com/vercel/next.js/tree/canary/examples/with-jest">Next.js with Jest and React Testing Library</a></li>
7+
<li><a href="https://github.com/vercel/next.js/tree/canary/examples/with-cypress">Next.js with Cypress</a></li>
8+
</ul>
9+
</details>
10+
11+
Learn how to set up Next.js with three commonly used testing tools: [Jest](https://jestjs.io/docs/tutorial-react), [React Testing Library](https://testing-library.com/docs/react-testing-library/intro/), and [Cypress](https://www.cypress.io/blog/2021/04/06/cypress-component-testing-react/).
12+
13+
## Jest and React Testing Library
14+
15+
Jest and React Testing Library are frequently used together for Unit Testing.
16+
17+
### Quickstart
18+
19+
You can use `create-next-app` with the [with-jest example](https://github.com/vercel/next.js/tree/canary/examples/with-jest) to quickly get started with Jest and React Testing Library:
20+
21+
```bash
22+
npx create-next-app --example with-jest with-jest-app
23+
```
24+
25+
### Manual setup
26+
27+
To manually set up Jest and React Testing Library, install `jest` , `@testing-library/react`, `@testing-library/jest-dom` as well as some supporting packages:
28+
29+
```bash
30+
npm install --save-dev jest babel-jest @testing-library/react @testing-library/jest-dom identity-obj-proxy react-test-renderer
31+
```
32+
33+
**Configuring Jest**
34+
35+
Create a `jest.config.js` file in your project's root directory and add the following configuration options:
36+
37+
```jsx
38+
// jest.config.js
39+
40+
module.exports = {
41+
collectCoverageFrom: [
42+
'**/*.{js,jsx,ts,tsx}',
43+
'!**/*.d.ts',
44+
'!**/node_modules/**',
45+
],
46+
moduleNameMapper: {
47+
// Handle CSS imports (with CSS modules)
48+
// https://jestjs.io/docs/webpack#mocking-css-modules
49+
'^.+\\.module\\.(css|sass|scss)$': 'identity-obj-proxy',
50+
51+
// Handle CSS imports (without CSS modules)
52+
'^.+\\.(css|sass|scss)$': '<rootDir>/__mocks__/styleMock.js',
53+
54+
// Handle image imports
55+
// https://jestjs.io/docs/webpack#handling-static-assets
56+
'^.+\\.(jpg|jpeg|png|gif|webp|svg)$': `<rootDir>/__mocks__/fileMock.js`,
57+
},
58+
testPathIgnorePatterns: ['<rootDir>/node_modules/', '<rootDir>/.next/'],
59+
transform: {
60+
// Use babel-jest to transpile tests with the next/babel preset
61+
// https://jestjs.io/docs/configuration#transform-objectstring-pathtotransformer--pathtotransformer-object
62+
'^.+\\.(js|jsx|ts|tsx)$': ['babel-jest', { presets: ['next/babel'] }],
63+
},
64+
transformIgnorePatterns: [
65+
'/node_modules/',
66+
'^.+\\.module\\.(css|sass|scss)$',
67+
],
68+
}
69+
```
70+
71+
You can learn more about each option above in the [Jest docs](https://jestjs.io/docs/configuration).
72+
73+
**Handling stylesheets and image imports**
74+
75+
These files aren't useful in tests but importing them may cause errors, so we will need to mock them. Create the mock files we referenced in the configuration above - `fileMock.js` and `styleMock.js` - inside a `__mocks__` directory:
76+
77+
```json
78+
// __mocks__/fileMock.js
79+
80+
(module.exports = "test-file-stub")
81+
```
82+
83+
```json
84+
// __mocks__/styleMock.js
85+
86+
module.exports = {};
87+
```
88+
89+
For more information on handling static assets, please refer to the [Jest Docs](https://jestjs.io/docs/webpack#handling-static-assets).
90+
91+
**Extend Jest with custom matchers**
92+
93+
`@testing-library/jest-dom` includes a set of convenient [custom matchers](https://github.com/testing-library/jest-dom#custom-matchers) such as `.toBeInTheDocument()` making it easier to write tests. You can import the custom matchers for every test by adding the following option to the Jest configuration file:
94+
95+
```json
96+
// jest.config.js
97+
98+
setupFilesAfterEnv: ['<rootDir>/jest.setup.js']
99+
```
100+
101+
Then, inside `jest.setup.js`, add the following import:
102+
103+
```jsx
104+
// jest.setup.js
105+
106+
import '@testing-library/jest-dom/extend-expect'
107+
```
108+
109+
If you need to add more setup options before each test, it's common to add them to the `jest.setup.js` file above.
110+
111+
**Absolute Imports and Module Path Aliases**
112+
113+
If your project is using [Module Path Aliases](https://nextjs.org/docs/advanced-features/module-path-aliases), you will need to configure Jest to resolve the imports by matching the paths option in the `jsconfig.json` file with the `moduleNameMapper` option in the `jest.config.js` file. For example:
114+
115+
```json
116+
// tsconfig.json or jsconfig.json
117+
{
118+
"compilerOptions": {
119+
"baseUrl": ".",
120+
"paths": {
121+
"@/components/*": ["components/*"]
122+
}
123+
}
124+
}
125+
```
126+
127+
```jsx
128+
// jest.config.js
129+
moduleNameMapper: {
130+
'^@/components/(.*)$': '<rootDir>/components/$1',
131+
}
132+
```
133+
134+
**Add a test script to package.json**
135+
136+
Add the Jest executable in watch mode to the `package.json` scripts:
137+
138+
```jsx
139+
"scripts": {
140+
"dev": "next dev",
141+
"build": "next build",
142+
"start": "next start",
143+
"test": "jest --watch"
144+
}
145+
```
146+
147+
`jest --watch` will re-run tests when a file is changed. For more Jest CLI options, please refer to the [Jest Docs](https://jestjs.io/docs/cli#reference).
148+
149+
**Create your first tests**
150+
151+
Your project is now ready to run tests. Follow Jests convention by adding tests to the `__tests__` folder in your project's root directory.
152+
153+
For example, we can add a test to check if the `<Index />` component successfully renders a heading:
154+
155+
```jsx
156+
// __tests__/testing-library.js
157+
import React from 'react'
158+
import { render } from '@testing-library/react'
159+
import Index from '../pages/index'
160+
161+
describe('App', () => {
162+
it('renders a heading', () => {
163+
const { getByRole } = render(<Index />)
164+
165+
const heading = getByRole('heading', {
166+
name: /welcome to next\.js!/i,
167+
})
168+
169+
expect(heading).toBeInTheDocument()
170+
})
171+
})
172+
```
173+
174+
Optionally, add a [snapshot test](https://jestjs.io/docs/snapshot-testing) to keep track of any unexpected changes to your `<Index />` component:
175+
176+
```jsx
177+
// __tests__/snapshot.js
178+
import React from 'react'
179+
import renderer from 'react-test-renderer'
180+
import Index from '../pages/index'
181+
182+
it('renders homepage unchanged', () => {
183+
const tree = renderer.create(<Index />).toJSON()
184+
expect(tree).toMatchSnapshot()
185+
})
186+
```
187+
188+
Test files should not be included inside the pages directory because any files inside the pages directory are considered routes.
189+
190+
**Running your test suite**
191+
192+
Run `npm run jest` to run your test suite. After your tests pass or fail, you will notice a list of interactive Jest commands that will be helpful as you add more tests.
193+
194+
For further reading, you may find these resources helpful:
195+
196+
- [Jest Docs](https://jestjs.io/docs/getting-started)
197+
- [React Testing Library Docs](https://testing-library.com/docs/react-testing-library/intro/)
198+
- [Testing Playground](https://testing-playground.com/) - use good testing practices to match elements.
199+
200+
## Cypress
201+
202+
Cypress is a test runner used for **End-to-End (E2E)** and **Integration Testing**.
203+
204+
### Quickstart
205+
206+
You can use `create-next-app` with the [with-cypress example](https://github.com/vercel/next.js/tree/canary/examples/with-jest) to quickly get started.
207+
208+
```bash
209+
npx create-next-app --example with-cypress with-cypress-app
210+
```
211+
212+
### Manual setup
213+
214+
To get started with Cypress, install the `cypress` package:
215+
216+
```bash
217+
npm install --save-dev cypress
218+
```
219+
220+
Add Cypress to the `package.json` scripts field:
221+
222+
```json
223+
"scripts": {
224+
"dev": "next dev",
225+
"build": "next build",
226+
"start": "next start",
227+
"cypress": "cypress open",
228+
}
229+
```
230+
231+
Run Cypress for the first time to generate examples that use their recommended folder structure:
232+
233+
```bash
234+
npm run cypress
235+
```
236+
237+
You can look through the generated examples and the [Writing Your First Test](https://docs.cypress.io/guides/getting-started/writing-your-first-test) section of the Cypress Documentation to help you get familiar with Cypress.
238+
239+
### Creating your first Cypress integration test
240+
241+
Assuming the following two Next.js pages:
242+
243+
```jsx
244+
// pages/index.js
245+
import Link from 'next/link'
246+
247+
export default function Home() {
248+
return (
249+
<nav>
250+
<Link href="/about">
251+
<a>About</a>
252+
</Link>
253+
</nav>
254+
)
255+
}
256+
```
257+
258+
```jsx
259+
// pages/about.js
260+
export default function About() {
261+
return (
262+
<div>
263+
<h1>About Page</h1>
264+
</div>
265+
)
266+
}
267+
```
268+
269+
Add a test to check your navigation is working correctly:
270+
271+
```jsx
272+
// cypress/integration/app.spec.js
273+
274+
describe('Navigation', () => {
275+
it('should navigate to the about page', () => {
276+
// Start from the index page
277+
cy.visit('http://localhost:3000/')
278+
279+
// Find a link with an href attribute containing "about" and click it
280+
cy.get('a[href*="about"]').click()
281+
282+
// The new url should include "/about"
283+
cy.url().should('include', '/about')
284+
285+
// The new page should contain an h1 with "About page"
286+
cy.get('h1').contains('About Page')
287+
})
288+
})
289+
```
290+
291+
You can use `cy.visit("/")` instead of `cy.visit("http://localhost:3000/")` if you add `"baseUrl": "http://localhost:3000"` to the `cypress.json` configuration file.
292+
293+
### Running your Cypress tests
294+
295+
Because Cypress is testing a real Next.js application, it requires the Next.js server to be running prior to starting Cypress. Run `npm run dev` to start the development server then run `npm run cypress` in another terminal window to start Cypress.
296+
297+
Alternatively, you can install the `start-server-and-test` package and add it to the `package.json` scripts field: `"test": "start-server-and-test dev http://localhost:3000 cypress"` to start the Next.js development server when you run Cypress.
298+
299+
### Getting ready for Continuous Integration (CI)
300+
301+
You will have noticed that running Cypress so far has opened an interactive browser which is not ideal for CI environments. You can also run Cypress headlessly using the `cypress run` command:
302+
303+
```json
304+
// package.json
305+
306+
"scripts": {
307+
//...
308+
"cypress": "cypress open",
309+
"cypress:headless": "cypress run",
310+
"e2e": "start-server-and-test dev http://localhost:3000 cypress",
311+
"e2e:headless": "start-server-and-test dev http://localhost:3000 cypress:headless"
312+
}
313+
```
314+
315+
You can learn more about Cypress and Continuous Integration from these resources:
316+
317+
- [Cypress Continuous Integration Docs](https://docs.cypress.io/guides/continuous-integration/introduction)
318+
- [Official Cypress Github Action](https://github.com/cypress-io/github-action)
319+
320+
## Community Packages and Examples
321+
322+
The Next.js community has created packages and articles you may find helpful:
323+
324+
- [next-page-tester](https://github.com/toomuchdesign/next-page-tester) for DOM Integration Testing.
325+
- [next-router-mock](https://github.com/scottrippey/next-router-mock) for Storybook.
326+
- [Test Preview Vercel Deploys with Cypress](https://glebbahmutov.com/blog/develop-preview-test/) by Gleb Bahmutov.
327+
328+
For more information on what to read next, we recommend:
329+
330+
<div class="card">
331+
<a href="/docs/basic-features/environment-variables#test-environment-variable.md">
332+
<b>Test Environment Variables</b>
333+
<small>Learn more test environments.</small>
334+
</a>
335+
</div>

errors/manifest.json

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -415,10 +415,6 @@
415415
"title": "import-esm-externals",
416416
"path": "/errors/import-esm-externals.md"
417417
},
418-
{
419-
"title": "max-custom-routes-reached",
420-
"path": "max-custom-routes-reached.md"
421-
},
422418
{
423419
"title": "static-page-generation-timeout",
424420
"path": "/errors/static-page-generation-timeout.md"

0 commit comments

Comments
 (0)