Skip to content

Commit

Permalink
Add Cypress tests, ESLint and Prettier to CI pipeline
Browse files Browse the repository at this point in the history
  • Loading branch information
WHL99 committed Jun 3, 2024
1 parent b038811 commit e48276e
Show file tree
Hide file tree
Showing 17 changed files with 5,618 additions and 1,332 deletions.
37 changes: 37 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{
"env": {
"browser": true,
"es2021": true,
"node": true
},
"extends": [
"eslint:recommended",
"plugin:react/recommended",
"plugin:@typescript-eslint/recommended",
"plugin:import/errors",
"plugin:import/warnings",
"plugin:import/typescript",
"prettier"
],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaFeatures": {
"jsx": true
},
"ecmaVersion": "latest",
"sourceType": "module"
},
"plugins": ["react", "@typescript-eslint", "import", "prettier"],
"rules": {
"prettier/prettier": "error",
"react/react-in-jsx-scope": "off",
"@typescript-eslint/no-unused-vars": "error",
"no-console": "warn",
"react/prop-types": "off"
},
"settings": {
"react": {
"version": "detect"
}
}
}
39 changes: 0 additions & 39 deletions .github/workflows/deploy.yml

This file was deleted.

84 changes: 84 additions & 0 deletions .github/workflows/nodejs-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# This workflow will do a clean installation of node dependencies, cache/restore them, build the source code and run tests across different versions of node
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-nodejs

name: Node.js CI

on: [push, pull_request]

jobs:
build:
permissions:
contents: write
runs-on: ubuntu-latest

strategy:
matrix:
node-version: [18.x]
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/

steps:
- name: Check Out Repository Code
uses: actions/checkout@v4

- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'
- name: Install Dependencies
run: npm ci

- name: Run Lint
run: npm run lint

- name: Run Prettier
run: npm run prettier-write

- name: Build the Source Code
run: npm run build --if-present

- name: Run Tests
run: npm test

- name: Run Cypress Tests
uses: cypress-io/github-action@v6
with:
config-file: cypress.config.ts
start: npm run dev
video: true
screenshots: true

- name: Upload Cypress Screenshots
if: always()
uses: actions/upload-artifact@v4
with:
name: cypress-screenshots
path: cypress/screenshots

- name: Upload Cypress Videos
if: always()
uses: actions/upload-artifact@v4
with:
name: cypress-videos
path: cypress/videos

# - name: Deploy with gh-pages
# run: |
# git remote set-url origin https://git:${GITHUB_TOKEN}@github.com/${GITHUB_REPOSITORY}.git
# npx gh-pages -d dist -u "github-actions-bot <[email protected]>"
# env:
# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
deploy:
needs: build
runs-on: ubuntu-latest

steps:
- name: Check Out Repository Code
uses: actions/checkout@v4

- name: Deploy with gh-pages
run: |
git remote set-url origin https://git:${GITHUB_TOKEN}@github.com/${GITHUB_REPOSITORY}.git
npx gh-pages -d dist -u "github-actions-bot <[email protected]>"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
10 changes: 10 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"tabWidth": 2,
"useTabs": false,
"singleQuote": true,
"printWidth": 100,
"semi": false,
"trailingComma": "all",
"jsxSingleQuote": true,
"bracketSpacing": true
}
74 changes: 37 additions & 37 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# Delivery Fee Calculator

<p align="center"><img width="900" alt="index" src="https://user-images.githubusercontent.com/104759740/214044615-da9bd859-8fb2-435b-83af-a0e9a893d423.jpg"></p>

## Setup
Expand All @@ -12,54 +13,53 @@
```
cd delivery-fee-calculator
```
- Install all npm package and run it:

- Install all npm package and run it:
```
npm install
npm run dev
```


## Folder Structure

```
delivery-fee-calculator
│ README.md
│ index.html
│ ...
|───public
│ └── calculator-icon.svg
|───cypress
│ └── e2e
│ └── test.cy.ts
└───src
|── utils
│ └── delivery.ts
│ main.tsx
│ App.tsx
│ App.test.tsx
│ App.css
│ package.json
│ ...
...
```

```
delivery-fee-calculator
│ README.md
│ index.html
│ ...
|───public
│ └── calculator-icon.svg
|───cypress
│ └── e2e
│ └── test.cy.ts
└───src
|── utils
│ └── delivery.ts
│ main.tsx
│ App.tsx
│ App.test.tsx
│ App.css
│ package.json
│ ...
...
- ```index.html``` is the only ```.html``` file for the entire React app. React app is displayed in this HTML page, more precisely in the ```<div id="root"></div>```. The entire app content is managed dynamically and displayed on this one HTML page.
- ```public``` folder contains a file that will be read by the browser while the app is being developing, which is ```calculator-icon.svg``` icon for head.
- ```utils``` folder has different functions which can be imported to ```App.tsx``` to caculate delivery fee under different conditions.
- ```main.tsx``` is the one where the main render call is happening by ReactDOM.render() method. The method ReactDOM.render() injects the React application into the ```<div id="root">``` so that the app can be rendered in the browser.
- ```App.tsx``` is a React component called “App”. This component will be the root component to all the other components. As this project is small, this is also a controlled components which control to submit a from.
- ```App.test.tsx``` is a set of tests runs against the sample App component that I start with. In this case I use [Vitest](https://vitest.dev/) which is a simple testing library built on top of [Vite](https://vitejs.dev/) which takes everything about [Jest](https://jestjs.io/).
- ```test.cy.ts``` contains end-to-end tests for this web application, ensuring its functionalities work correctly. It tests various scenarios including fee calculation during rush and non-rush hours, as well as validation for incorrect inputs. I use [Cypress](https://www.cypress.io/) as the framework.
- ```App.css``` stores styling targeting the App component specifically.
- ```package.json``` lists all the dependencies and scripts needed to run the React app successfully.
```

- `index.html` is the only `.html` file for the entire React app. React app is displayed in this HTML page, more precisely in the `<div id="root"></div>`. The entire app content is managed dynamically and displayed on this one HTML page.
- `public` folder contains a file that will be read by the browser while the app is being developing, which is `calculator-icon.svg` icon for head.
- `utils` folder has different functions which can be imported to `App.tsx` to caculate delivery fee under different conditions.
- `main.tsx` is the one where the main render call is happening by ReactDOM.render() method. The method ReactDOM.render() injects the React application into the `<div id="root">` so that the app can be rendered in the browser.
- `App.tsx` is a React component called “App”. This component will be the root component to all the other components. As this project is small, this is also a controlled components which control to submit a from.
- `App.test.tsx` is a set of tests runs against the sample App component that I start with. In this case I use [Vitest](https://vitest.dev/) which is a simple testing library built on top of [Vite](https://vitejs.dev/) which takes everything about [Jest](https://jestjs.io/).
- `test.cy.ts` contains end-to-end tests for this web application, ensuring its functionalities work correctly. It tests various scenarios including fee calculation during rush and non-rush hours, as well as validation for incorrect inputs. I use [Cypress](https://www.cypress.io/) as the framework.
- `App.css` stores styling targeting the App component specifically.
- `package.json` lists all the dependencies and scripts needed to run the React app successfully.

## Framework and Tool

- [Vite](https://vitejs.dev/) : This is a small project, I can just use create-react-app, but I choose Vite becasue it runs much faster than create-react-app.

- [Material UI](https://mui.com/material-ui/) : Their components are easy to customize and integrate. Especially its [date and time picker](https://dev.material-ui-pickers.dev/api/DateTimePicker) meets my needs in the project.
Expand Down
2 changes: 1 addition & 1 deletion cypress.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { defineConfig } from 'cypress'

export default defineConfig({
e2e: {
setupNodeEvents(on, config) {},
setupNodeEvents() {},
baseUrl: 'http://localhost:5173/',
},
})
13 changes: 3 additions & 10 deletions cypress/e2e/test.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,7 @@ describe('Delivery Fee Calculator Tests', () => {

cy.getDataTestId('your-delivery-price').should('be.visible')

cy.getDataTestId('delivery-price')
.should('not.be.empty')
.and('have.text', '2 €')
cy.getDataTestId('delivery-price').should('not.be.empty').and('have.text', '2 €')
})

it('caculates the delivery price correctly (in rush hour)', () => {
Expand Down Expand Up @@ -73,9 +71,7 @@ describe('Delivery Fee Calculator Tests', () => {

cy.getDataTestId('your-delivery-price').should('be.visible')

cy.getDataTestId('delivery-price')
.should('not.be.empty')
.and('have.text', '2.4 €')
cy.getDataTestId('delivery-price').should('not.be.empty').and('have.text', '2.4 €')
})

it('shows error messages for invalid inputs', () => {
Expand Down Expand Up @@ -108,9 +104,6 @@ describe('Delivery Fee Calculator Tests', () => {

cy.getDataTestId('submit-button').click()

cy.get('.MuiFormHelperText-root').and(
'have.text',
'This field is required.',
)
cy.get('.MuiFormHelperText-root').and('have.text', 'This field is required.')
})
})
1 change: 1 addition & 0 deletions cypress/support/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ Cypress.Commands.add('getDataTestId', (dataTestSelector: string) => {
})

declare global {
// eslint-disable-next-line @typescript-eslint/no-namespace
namespace Cypress {
interface Chainable {
getDataTestId(dataTestSelector: string): Chainable<JQuery<HTMLElement>>
Expand Down
2 changes: 1 addition & 1 deletion cypress/support/e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,4 @@
import './commands'

// Alternatively you can use CommonJS syntax:
// require('./commands')
// require('./commands')
2 changes: 1 addition & 1 deletion index.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<!DOCTYPE html>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
Expand Down
Loading

0 comments on commit e48276e

Please sign in to comment.