Skip to content

Commit 2c73b95

Browse files
committed
add cypress and coverage reporting
1 parent b7b91b9 commit 2c73b95

27 files changed

+2796
-291
lines changed

.babelrc

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"presets": ["next/babel"],
3+
"plugins": ["istanbul"]
4+
}

.gitignore

+3-2
Original file line numberDiff line numberDiff line change
@@ -30,5 +30,6 @@ yarn-error.log*
3030
.env.test.local
3131
.env.production.local
3232

33-
# vercel
34-
.vercel
33+
# coverage
34+
.nyc_output
35+
cypress-coverage

.nycrc.json

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"extension": [".js", ".jsx", ".ts", ".tsx"],
3+
"extends": "@istanbuljs/nyc-config-typescript",
4+
"include": ["pages/**/*"],
5+
"exclude": ["pages/api/__coverage__.js"],
6+
"all": true,
7+
"sourceMap": true,
8+
"instrument": true
9+
}

@types/files.d.ts

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
declare module '*.module.css' {
2+
const classes: { [key: string]: string };
3+
export default classes;
4+
}

@types/nextjs-types.d.ts

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
/// <reference types="next" />
2+
/// <reference types="next/types/global" />

README.md

+7-16
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
1+
This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app) for the express purpose of demonstrating Next.js, TypeScript, and Cypress working together with working coverage reports.
22

33
## Getting Started
44

@@ -12,19 +12,10 @@ yarn dev
1212

1313
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
1414

15-
You can start editing the page by modifying `pages/index.js`. The page auto-updates as you edit the file.
15+
Then open the Cypress test runner:
1616

17-
## Learn More
18-
19-
To learn more about Next.js, take a look at the following resources:
20-
21-
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
22-
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
23-
24-
You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
25-
26-
## Deploy on Vercel
27-
28-
The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/import?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
29-
30-
Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
17+
```bash
18+
npm run cypress open
19+
# or
20+
yarn cypress open
21+
```

cypress.json

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"baseUrl": "http://localhost:3000",
3+
"nodeVersion": "system",
4+
"env": {
5+
"codeCoverage": {
6+
"url": "/api/__coverage__"
7+
}
8+
}
9+
}

cypress/fixtures/example.json

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"name": "Using fixtures to represent data",
3+
"email": "[email protected]",
4+
"body": "Fixtures are a great way to mock data for responses to routes"
5+
}

cypress/integration/about.spec.ts

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
describe('app', () => {
2+
it('redirects to /', () => {
3+
cy.visit('/about');
4+
cy.location('pathname').should('equal', '/');
5+
cy.findByTestId('landing_page').should('exist').and('be.visible');
6+
});
7+
});

cypress/integration/index.spec.ts

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
describe('landing', () => {
2+
it('should render', () => {
3+
cy.visitAndWaitFor('/', 'landing_page');
4+
});
5+
});

cypress/plugins/index.ts

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// ***********************************************************
2+
/// <reference types="cypress" />
3+
4+
// This example plugins/index.js can be used to load plugins
5+
//
6+
// You can change the location of this file or turn off loading
7+
// the plugins file with the 'pluginsFile' configuration option.
8+
//
9+
// You can read more here:
10+
// https://on.cypress.io/plugins-guide
11+
// ***********************************************************
12+
13+
// This function is called when a project is opened or re-opened (e.g. due to
14+
// the project's config changing)
15+
16+
const pluginConfig: Cypress.PluginConfig = (on, config) => {
17+
// `on` is used to hook into various events Cypress emits
18+
// `config` is the resolved Cypress config
19+
20+
const browserify = require('@cypress/browserify-preprocessor');
21+
const options = browserify.defaultOptions;
22+
options.browserifyOptions.transform[1][1].babelrc = true;
23+
options.typescript = require.resolve('typescript');
24+
25+
require('@cypress/code-coverage/task')(on, config);
26+
on('file:preprocessor', browserify(options));
27+
28+
return config;
29+
};
30+
31+
module.exports = pluginConfig;

cypress/support/commands.ts

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// ***********************************************
2+
// This example commands.js shows you how to
3+
// create various custom commands and overwrite
4+
// existing commands.
5+
//
6+
// For more comprehensive examples of custom
7+
// commands please read more here:
8+
// https://on.cypress.io/custom-commands
9+
// ***********************************************
10+
//
11+
//
12+
// -- This is a parent command --
13+
// Cypress.Commands.add("login", (email, password) => { ... })
14+
//
15+
//
16+
// -- This is a child command --
17+
// Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... })
18+
//
19+
//
20+
// -- This is a dual command --
21+
// Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... })
22+
//
23+
//
24+
// -- This will overwrite an existing command --
25+
// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... })
26+
import '@testing-library/cypress/add-commands';
27+
28+
/**
29+
* NOTE: If you add a custom command, please add types for it.
30+
* @see https://docs.cypress.io/guides/tooling/typescript-support.html#Types-for-custom-commands
31+
* */
32+
33+
Cypress.Commands.add('visitAndWaitFor', (pathname, testId) => {
34+
cy.visit(pathname);
35+
cy.findByTestId(testId).should('exist').and('be.visible');
36+
});

cypress/support/index.d.ts

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// in cypress/support/index.d.ts
2+
// load type definitions that come with Cypress module
3+
/// <reference types="cypress" />
4+
5+
declare namespace Cypress {
6+
interface Chainable {
7+
/**
8+
* @description Custom command to bootstrap initial page visit
9+
* @param pathname - the path you want to end up on before tests execute
10+
* @param testId - the test id of the element that should be visible before tests execute
11+
* @example cy.visitAndWaitFor('/contact', 'contact_page_hero_banner')
12+
*/
13+
visitAndWaitFor(pathname: string, testId: string): void;
14+
}
15+
}

cypress/support/index.ts

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// ***********************************************************
2+
// This example support/index.js is processed and
3+
// loaded automatically before your test files.
4+
//
5+
// This is a great place to put global configuration and
6+
// behavior that modifies Cypress.
7+
//
8+
// You can change the location of this file or turn off
9+
// automatically serving support files with the
10+
// 'supportFile' configuration option.
11+
//
12+
// You can read more here:
13+
// https://on.cypress.io/configuration
14+
// ***********************************************************
15+
16+
// Import commands.js using ES2015 syntax:
17+
import './commands';
18+
import '@cypress/code-coverage/support';

cypress/tsconfig.json

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"extends": "../tsconfig.json",
3+
"compilerOptions": {
4+
"baseUrl": "../.",
5+
"isolatedModules": false
6+
},
7+
"files": ["./support/index.d.ts"],
8+
"include": ["**/*.ts", "../@types/*.d.ts"]
9+
}

next-env.d.ts

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
/// <reference types="next" />
2+
/// <reference types="next/types/global" />

package.json

+24-1
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,38 @@
11
{
22
"name": "cypress-coverage",
3-
"version": "0.1.0",
3+
"version": "1.0.0",
44
"private": true,
55
"scripts": {
66
"dev": "next dev",
77
"build": "next build",
8+
"see-cy-coverage": "open ./cypress-coverage/lcov-report/index.html",
89
"start": "next start"
910
},
1011
"dependencies": {
1112
"next": "9.5.4",
1213
"react": "16.13.1",
1314
"react-dom": "16.13.1"
15+
},
16+
"nyc": {
17+
"extends": "./.nycrc.json",
18+
"report-dir": "cypress-coverage",
19+
"reporter": [
20+
"json",
21+
"lcov"
22+
]
23+
},
24+
"devDependencies": {
25+
"@cypress/browserify-preprocessor": "^3.0.1",
26+
"@cypress/code-coverage": "^3.8.1",
27+
"@istanbuljs/nyc-config-typescript": "^1.0.1",
28+
"@testing-library/cypress": "^7.0.1",
29+
"@types/node": "^14.11.7",
30+
"@types/react": "^16.9.51",
31+
"@types/react-dom": "^16.9.8",
32+
"@types/testing-library__cypress": "^5.0.8",
33+
"babel-plugin-istanbul": "^6.0.0",
34+
"cypress": "^5.3.0",
35+
"nyc": "^15.1.0",
36+
"typescript": "^4.0.3"
1437
}
1538
}

pages/_app.js

-7
This file was deleted.

pages/_app.tsx

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { NextComponentType } from 'next';
2+
import '../styles/globals.css';
3+
4+
interface CustomAppProps {
5+
Component: NextComponentType;
6+
pageProps: { [key: string]: any };
7+
}
8+
9+
function App({ Component, pageProps }: CustomAppProps) {
10+
return <Component {...pageProps} />;
11+
}
12+
13+
export default App;

pages/about.tsx

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { useRouter } from 'next/router';
2+
import { useEffect, useState } from 'react';
3+
4+
export default function About() {
5+
const router = useRouter();
6+
const [isMounted, setIsMounted] = useState(false);
7+
8+
useEffect(() => {
9+
setIsMounted(true);
10+
router.replace('/');
11+
}, []);
12+
13+
if (!isMounted) {
14+
return null;
15+
}
16+
17+
return <>You should never see this</>;
18+
}

pages/api/__coverage__.js

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
module.exports = require('@cypress/code-coverage/middleware/nextjs');

pages/api/hello.js

-6
This file was deleted.

pages/index.js

-65
This file was deleted.

pages/index.tsx

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import Link from 'next/link';
2+
import Head from 'next/head';
3+
import styles from '../styles/Home.module.css';
4+
5+
export default function Home() {
6+
return (
7+
<div className={styles.container}>
8+
<Head>
9+
<title>Next.js + Cypress</title>
10+
<link rel="icon" href="/favicon.ico" />
11+
</Head>
12+
13+
<main className={styles.main} data-testid="landing_page">
14+
<h1 className={styles.title}>
15+
Welcome to the TypeScript <a href="https://nextjs.org">Next.js</a>{' '}
16+
Cypress example.
17+
</h1>
18+
19+
<div className={styles.linkContainer}>
20+
<Link href="/about">
21+
<a data-testid="about_page_link">Try going to about page...</a>
22+
</Link>
23+
<>(you can't lol, idk)</>
24+
</div>
25+
</main>
26+
</div>
27+
);
28+
}

0 commit comments

Comments
 (0)