Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/e2e-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
name: Run E2E tests on deployment success
if: github.event.deployment_status.state == 'success'
runs-on: ubuntu-latest
container: cypress/included:8.7.0
container: cypress/included:9.5.4
env:
NPM_RC: ${{ secrets.NPM_TOKEN }}
TERM: xterm
Expand Down
12 changes: 6 additions & 6 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name: CI
on: [push]

env:
NODE_VERSION: 14.x
NODE_VERSION: 16.x

jobs:
install:
Expand All @@ -13,10 +13,10 @@ jobs:
- name: CI
uses: actions/checkout@v3
- name: Use Node ${{ env.NODE_VERSION }}
uses: actions/setup-node@v2
uses: actions/setup-node@v3
with:
node-version: ${{ env.NODE_VERSION }}
- uses: actions/cache@v2
- uses: actions/cache@v3
with:
path: '**/node_modules'
key: ${{ runner.os }}-${{ env.NODE_VERSION }}-modules-${{ hashFiles('**/yarn.lock') }}
Expand All @@ -32,7 +32,7 @@ jobs:
steps:
- name: Running lint
uses: actions/checkout@v3
- uses: actions/cache@v2
- uses: actions/cache@v3
with:
path: '**/node_modules'
key: ${{ runner.os }}-${{ env.NODE_VERSION }}-modules-${{ hashFiles('**/yarn.lock') }}
Expand All @@ -48,7 +48,7 @@ jobs:
steps:
- name: Running tests
uses: actions/checkout@v3
- uses: actions/cache@v2
- uses: actions/cache@v3
with:
path: '**/node_modules'
key: ${{ runner.os }}-${{ env.NODE_VERSION }}-modules-${{ hashFiles('**/yarn.lock') }}
Expand All @@ -68,7 +68,7 @@ jobs:
steps:
- name: Build
uses: actions/checkout@v3
- uses: actions/cache@v2
- uses: actions/cache@v3
with:
path: '**/node_modules'
key: ${{ runner.os }}-${{ env.NODE_VERSION }}-modules-${{ hashFiles('**/yarn.lock') }}
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

# A quick start Redux + TypeScript Create React App template

An opinionated quick start [Create React App](https://github.com/facebook/create-react-app) (CRA) _template_ with configured **Redux**, **TypeScript**, **React Router**, **Enzyme** and custom **ESlint** configuration.
An opinionated quick start [Create React App](https://github.com/facebook/create-react-app) (CRA) _template_ with configured **Redux**, **TypeScript**, **React Router**, **React Testing Library** and custom **ESlint** configuration.

Original Create React App README available [here](./README_CRA.md)

Expand Down Expand Up @@ -53,7 +53,7 @@ The template provides basic Redux configuration with [feature based](https://red

## Testing

Testing is done with [Enzyme](https://airbnb.io/enzyme/).
Testing is done with [React Testing Library](https://testing-library.com/docs/react-testing-library/intro/).

## [Prettier](https://prettier.io/)

Expand Down
14 changes: 14 additions & 0 deletions cypress.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { defineConfig } from 'cypress'

export default defineConfig({
video: false,
retries: 1,
e2e: {
// We've imported your old cypress plugins here.
// You may want to clean this up later by importing these.
setupNodeEvents: function (on, config) {
return require('./cypress/plugins/index.js')(on, config)
},
baseUrl: 'http://localhost:3000',
},
})
5 changes: 0 additions & 5 deletions cypress.json

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
/* eslint-disable no-undef */
describe('About page', () => {
beforeEach(() => {
cy.visit('/about')
Expand All @@ -12,7 +11,7 @@ describe('About page', () => {

it('should navigate to the about page and back via header link', () => {
cy.get('h1').contains('About')
cy.get('[cy-data="home-nav-link"] > .active').click()
cy.get('[cy-data="home-nav-link"]').click()
cy.get('h1').contains('Redux + TypeScript')
})
})
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
/* eslint-disable no-undef */
describe('counter', () => {
beforeEach(() => {
cy.visit('/')
Expand Down
1 change: 1 addition & 0 deletions cypress/support/e2e.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import './commands'
36 changes: 17 additions & 19 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,16 @@
"license": "MIT",
"author": "Alexander Grischuk <alexgrischuk@gmail.com",
"engines": {
"node": ">=10"
"node": ">=16.0.0 <20.0.0"
},
"main": "template.json",
"description": "A quick start Create React App template with React Router, Redux, TypeScript, Enzyme and custom ESlint configurations",
"description": "A quick start Create React App template with React Router, Redux, TypeScript, React Testing Library and custom ESlint configurations",
"keywords": [
"react",
"create-react-app",
"cra-template",
"template",
"enzyme",
"react-testing-library",
"eslint",
"redux",
"react-redux",
Expand All @@ -35,18 +35,14 @@
"url": "https://github.com/alexandr-g/cra-template-typescript-redux/issues"
},
"dependencies": {
"@types/enzyme": "^3.10.4",
"@types/jest": "^27.0.0",
"@testing-library/react": "^14.0.0",
"@types/node": "^14.0.0",
"@types/react": "^17.0.0",
"@types/react-dom": "^17.0.0",
"@types/react-redux": "^7.1.5",
"@types/react-router-dom": "^5.1.3",
"@types/react": "^18.2.6",
"@types/react-dom": "^18.2.4",
"@types/react-router-dom": "^5.3.3",
"@types/redux-mock-store": "^1.0.1",
"@typescript-eslint/eslint-plugin": "^5.59.5",
"@typescript-eslint/parser": "5.9.1",
"@wojtekmaj/enzyme-adapter-react-17": "^0.6.0",
"enzyme": "^3.11.0",
"eslint": "^8.6.0",
"eslint-config-airbnb-typescript": "^16.1.0",
"eslint-config-prettier": "^8.0.0",
Expand All @@ -56,12 +52,12 @@
"eslint-plugin-react": "^7.21.5",
"eslint-plugin-react-hooks": "^4.0.8",
"prettier": "^2.0.0",
"react": "^17.0.0",
"react-dom": "^17.0.0",
"react-redux": "^7.1.3",
"react-router-dom": "^5.1.2",
"react-scripts": "5.0.0",
"redux": "^4.0.5",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-redux": "^8.0.5",
"react-router-dom": "^6.11.1",
"react-scripts": "^5.0.1",
"redux": "^4.2.1",
"redux-devtools-extension": "^2.13.8",
"redux-mock-store": "^1.5.4",
"typescript": "~4.5.0"
Expand All @@ -78,7 +74,7 @@
"lint": "eslint src --ext .js,.jsx,.ts,.tsx",
"fix": "eslint src --ext .js,.jsx,.ts,.tsx --fix",
"format": "prettier --write src/**/*.{ts,tsx}",
"e2e": "cypress run --spec 'cypress/integration/*'"
"e2e": "cypress run --env device=web"
},
"eslintConfig": {
"extends": "react-app"
Expand Down Expand Up @@ -110,12 +106,14 @@
]
},
"devDependencies": {
"@babel/runtime": "^7.21.5",
"@semantic-release/changelog": "6.0.1",
"@semantic-release/git": "10.0.1",
"@semantic-release/github": "8.0.2",
"@testing-library/jest-dom": "^5.16.5",
"codecov": "3.8.3",
"commitizen": "4.2.4",
"cypress": "9.4.1",
"cypress": "^12.12.0",
"cz-conventional-changelog": "3.3.0",
"eslint-plugin-cypress": "2.12.1",
"semantic-release": "18.0.1"
Expand Down
10 changes: 5 additions & 5 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react'
import { BrowserRouter, Switch, Route } from 'react-router-dom'
import { BrowserRouter, Routes, Route } from 'react-router-dom'

import { Navbar } from './components/Navbar'
import { About } from './pages/About'
Expand All @@ -10,10 +10,10 @@ const App: React.FC = () => {
<BrowserRouter>
<Navbar />
<div className="container">
<Switch>
<Route path="/" component={Home} exact />
<Route path="/about" component={About} />
</Switch>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
</Routes>
</div>
</BrowserRouter>
)
Expand Down
35 changes: 15 additions & 20 deletions src/components/counter/Counter.spec.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import React from 'react'
import { render, screen, fireEvent } from '@testing-library/react'
import { Provider } from 'react-redux'
import { mount } from 'enzyme'
import configureStore from 'redux-mock-store'

import { actionTypes } from '../../features/counter'
Expand All @@ -17,47 +16,43 @@ describe('Counter', () => {
// Add jest mock spy to watch for store.dispatch method. See https://jestjs.io/docs/en/jest-object#jestspyonobject-methodname for more info
jest.spyOn(store, 'dispatch')

it('renders without crashing.', () => {
const wrapper = mount(
test('renders without crashing.', () => {
render(
<Provider store={store}>
<Counter />
</Provider>
)

const countValue = wrapper.find('strong').text()
expect(countValue).toBe('42')
const countValue = screen.getByText('42')
expect(countValue).toBeInTheDocument()
})

it('should be possible to increment counter.', () => {
const wrapper = mount(
test('should be possible to increment counter.', () => {
render(
<Provider store={store}>
<Counter />
</Provider>
)

wrapper
.find('button')
.filter({ 'data-qa': 'increment-counter' })
.simulate('click')
const incrementButton = screen.getByRole('button', { name: 'increment' })
fireEvent.click(incrementButton)

expect(store.dispatch).toBeCalledTimes(1)
expect(store.dispatch).toHaveBeenCalledTimes(1)

expect(store.dispatch).toBeCalledWith({
expect(store.dispatch).toHaveBeenCalledWith({
type: actionTypes.INCREMENT_COUNTER,
})
})

it('should be possible to decrement counter.', () => {
const wrapper = mount(
test('should be possible to decrement counter.', () => {
render(
<Provider store={store}>
<Counter />
</Provider>
)

wrapper
.find('button')
.filter({ 'data-qa': 'decrement-counter' })
.simulate('click')
const decrementButton = screen.getByRole('button', { name: 'decrement' })
fireEvent.click(decrementButton)

expect(store.dispatch).toHaveBeenCalledTimes(1)

Expand Down
4 changes: 2 additions & 2 deletions src/features/counter/counterReducer.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import counterReducer from './counterReducer'
import { CounterActionTypes } from './types'

describe('features > counter > counterReducer', () => {
it(`increments value, if ${INCREMENT_COUNTER} action is provided`, () => {
test(`increments value, if ${INCREMENT_COUNTER} action is provided`, () => {
const initialState = {
value: 0,
}
Expand All @@ -19,7 +19,7 @@ describe('features > counter > counterReducer', () => {
expect(counterReducer(initialState, action)).toEqual(expectedState)
})

it(`increments value, if ${DECREMENT_COUNTER} action is provided`, () => {
test(`increments value, if ${DECREMENT_COUNTER} action is provided`, () => {
const initialState = {
value: 0,
}
Expand Down
11 changes: 6 additions & 5 deletions src/index.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
import React from 'react'
import ReactDOM from 'react-dom'
import { createRoot } from 'react-dom/client'
import { Provider } from 'react-redux'
import store from './store'

import './index.css'

import App from './App'

ReactDOM.render(
const container = document.getElementById('root') as HTMLDivElement
const root = createRoot(container!)

root.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
</Provider>
)
6 changes: 3 additions & 3 deletions src/pages/About.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import React, { Fragment } from 'react'
import { useHistory } from 'react-router-dom'
import { useNavigate } from 'react-router-dom'

export const About: React.FC = () => {
const history = useHistory()
const navigate = useNavigate()

return (
<Fragment>
Expand All @@ -17,7 +17,7 @@ export const About: React.FC = () => {
type="button"
className="btn"
cy-data="go-back-button"
onClick={() => history.push('/')}
onClick={() => navigate('/')}
>
Go back
</button>
Expand Down
4 changes: 2 additions & 2 deletions src/pages/Home.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ export const Home: React.FC = () => {
<h1>Redux + TypeScript</h1>
<p>
Hello and welcome! :) This app was generated by the Create React App
template and bootstrapped with Redux, React Router, TypeScript, ESlint,
Prettier for you. Take a look around ;)
template and bootstrapped with Redux, React Router, React Testing
Library, TypeScript, ESlint, Prettier for you. Take a look around ;)
</p>
<Counter />
</Fragment>
Expand Down
5 changes: 1 addition & 4 deletions src/setupTests.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1 @@
import { configure } from 'enzyme'
import Adapter from '@wojtekmaj/enzyme-adapter-react-17'

configure({ adapter: new Adapter() })
import '@testing-library/jest-dom'
Loading