An user-facing web application and is currently supporting basic authentication features
- Table of contents
- App first look
- Project Overview
- Run the app locally
- Testing
- Continuous Integration (CI)
- Future Enhancements
- Challenges and Solutions
Sparkol app is a user-facing web application with the following user stories implemented:
- User can logs in to the application on the login page.
- User can explore the homepage, a protected route, after logged in to see a greeting message.
- User can sign out from the application on the homepage after logged in.
- Login with username and password
- Form validation:
- Username and password are required
- Display a hint message below the input filed when username or password is invalid
- Display an error message on top of the form when login failed
- Redirect the user to the home page after login successfully
- Display a greeting message with the username
- Show a logout button:
- Log out current user and redirect them to the login page after clicking the button
- Persist user login status:
- Login status will be persisted after refreshing the page
- Redirect the user to the login page if the data is missing in the local storage
- Display a 404 page when the user tries to access a non-existing route
- Display a button for the user to get back to the home page(or login page if the user is not logged in)
- Redirect the user to the login page if subsequent requests to protected API routes are failed due to unauthorized access
- React: For building user interfaces.
- React Router: For routing in React.
- TypeScript: For static type checking.
- Vite: Used as a local development server and build tool.
- styled-components: For writing CSS in JS in React.
- ESLint: For code linting.
- Prettier: For code formatting.
- axios: For making HTTP requests.
- Vitest: For unit testing.
- React Testing Library: For testing React components.
- Happy Dom: Used as a JavaScript implementation of a web browser for testing.
- Cypress: For end-to-end testing.
- GitHub Actions: For continuous integration.
- vite-plugin-svgr: For transforming SVGs into React components in Vite.
- Sparkol Authentication Service: For user authentication.
The following instructions will go through the setting needed to run the front-end app on your local machine.
git clone https://github.com/smallpaes/sparkol-app.git
1. Enter the project folder
Open a new terminal and enter the folder
$ cd sparkol-app
2. Install packages via npm
$ npm install
3. Create .env file
$ touch .env
4. Added env variables
The value should be the back-end api endpoint.
VITE_API_BASE_URL=
5. Run the app for development
Please make sure the backend server is running.
$ npm run dev
1. Code linting
$ npm run lint
2. Code formatting
$ npm run format
3. Unit testing (Either one)
$ npm run test
$ npm t
4. Test coverage report generation for unit testing
$ npm run test:coverage
View the report in the browser:
$ open ./coverage/index.html
5. E2E testing using Cypress
Start the server:
$ npm run dev
Run the test using Cypress:
$ npm run cy:open
6. E2E testing headlessly with recording
$ npm run cy:run
- Focused on small functionalities that could be used in one or more components first: Tested custom hooks and helper functions.
- Tested the components: UI and user interactions.
- Generated a coverage report to check the test coverage:
- Tested the login flow: Made sure the user can log in to the application successfully and be redirected to the home page.
- Tested the login functionalities: Handled different scenario on the login page.
- Tested the logout flow: Made sure the user can log out from the application successfully on the home page.
- Tested route protection: Made sure the user can't access the home page without logging in and will be redirected to the login page.
- Generated the testing report:
The project utilizes GitHub Actions as the primary tool for implementing a robust continuous integration (CI) process. The CI pipeline is triggered automatically whenever changes are pushed to the main branch, ensuring the reliability and quality of the application codebase. The CI process includes the following steps:
- The CI pipeline executes the Cypress end-to-end testing to validate the application's behavior and interactions, ensuring its overall functionality and user experience.
-
The CI pipeline executes the Cypress end-to-end testing, which validate the application's functionality and user flows from a user's perspective.
-
The test results are recorded and sent to Cypress Cloud, a testing platform that provides in-depth and shareable test reports.
-
Cypress Cloud offers valuable features such as quick access to error messages, stack traces, screenshots, videos, and contextual details, facilitating efficient debugging and issue resolution.
-
The CI process starts the build process to ensures that the codebase is in a deployable state and ready for further testing.
-
After that, the pipeline proceeds to running unit testing that validates the functionality of individual components, functions, and custom hooks within the application.
- Status badges on the README file to provide a quick overview of the CI pipeline's status:
Some potential improvements that could be made to the application to provide a better user experience and code maintainability across the team:
Might consider using TanStack Query for data fetching as it provides some benefits:
- Fetching state will be handled by the library.
- Automatic caching, refetching, and updating of data--Could be useful if there are other APIs that need to be integrated into the application in the future.
Creates more mixins using styled-components, allowing the CSS code to be reused across the application.
Even though the test coverage is already high, there are still some areas that could be improved, such as unit testing for context.
During the development of this project, there are some challenges that allowed me to learn and implement new technologies and practices. Here are some of them and how I addressed them:
One of the challenges I encountered was ensuring the reliability and stability of the codebase. To overcome this, I adopted a unit testing approach using Vitest and React Testing Library. This process allows me think about how I should structure and refactor my components, functions, custom hooks for easier testing.
To ensure end-to-end functionality and simulate real-world user interactions, I integrated Cypress into the project for comprehensive end-to-end testing. Cypress allowed me to write tests that cover multiple components, interactions, and API integrations. The process allowed me to think about the use case from the users' perspective and ensure the application's overall functionality and user experience.
As the backend server should be run locally at this moment before the frontend application could call the API, I tried to mock the API response in Cypress to make sure the frontend functionalities could work properly without having to integrate with the real API.
As part of the development process, I wanted to automate CI process to ensure consistent quality and reliability, therefore, I integrated GitHub Actions into the project, which provided a robust and flexible CI solution.
To make the development process more efficient among the team, I created or used:
- Common theme and basic mixins using styled-components.
- ESLint and Prettier for code linting and formatting.
- Github pull request template to make sure the PRs are following the same format and contain the necessary information.
- CI pipeline to ensure the codebase is in a deployable state and passed the necessary testing.