diff --git a/README.md b/README.md index 20b4126..7370bb2 100644 --- a/README.md +++ b/README.md @@ -1,98 +1,39 @@ -# zipBoard Junior Position Test Project - -This is a test repository for the zipBoard junior position application process. This project demonstrates a simple React application with a login form and Cypress testing setup. - -## Important Note - -This repository is for testing purposes only. Please fork this repository to your own account and do not modify this original repository. All your work should be done in your forked version. - -## Required Technologies - -To run this project locally, you need to have the following installed: - -- Node.js (version 18 or higher) -- npm (comes with Node.js) -- Git - -## Getting Started - -1. Fork this repository to your own account -2. Clone your forked repository: - ```bash - git clone - ``` -3. Install dependencies: - ```bash - npm install - ``` -4. Start the development server: - ```bash - npm start - ``` - The application will be available at [http://localhost:3000](http://localhost:3000) - -## Testing with Cypress - -This project uses Cypress for end-to-end testing. To run the tests: - -1. Make sure the development server is running (`npm start`) -2. In a new terminal, you can run Cypress in two ways: - - ### Open Cypress Test Runner (Interactive Mode) - ```bash - npm run cypress:open - ``` - This will open the Cypress Test Runner UI where you can: - - Choose your preferred browser - - See all test files - - Run tests interactively - - Watch tests run in real-time - - ### Run Tests in Headless Mode - ```bash - npm run cypress:run - ``` - This will run all tests in the terminal without opening the UI. - - ### Run Tests with Dev Server - ```bash - npm run test:e2e - ``` - This command will: - 1. Start the development server - 2. Wait for it to be available - 3. Run all Cypress tests - 4. Shut down the server when done - -## Project Structure - -``` -├── src/ -│ ├── components/ -│ │ ├── LoginForm.js -│ │ ├── LoginForm.css -│ │ ├── Welcome.js -│ │ └── Welcome.css -│ ├── App.js -│ └── App.css -├── cypress/ -│ ├── e2e/ -│ │ └── login.cy.js -│ └── support/ -│ ├── commands.js -│ └── e2e.js -└── package.json -``` - -## Available Scripts - -- `npm start` - Runs the app in development mode -- `npm test` - Runs the React testing suite -- `npm run build` - Builds the app for production -- `npm run cypress:open` - Opens Cypress Test Runner -- `npm run cypress:run` - Runs Cypress tests in headless mode -- `npm run test:e2e` - Runs Cypress tests with the dev server - -## License - -This project is for testing purposes only and is not licensed for public use. +# 🧪 React Login App: Cypress Test + Bug Fix + +This project is a simple login application built with React. It includes a basic login form and a welcome screen. The project also includes Cypress end-to-end (E2E) tests to ensure that the login flow works as expected. + +--- + +## ✅ Bug Fix: Login Redirect Not Working + +### 🔍 Problem + +The login form did not redirect the user to the welcome screen after submitting valid input. Clicking "Login" did not cause any state change in the app. + +### 🛠️ Fix + +The form inside `LoginForm.jsx` was missing an `onSubmit` handler. This caused the `onLogin` callback (passed from the parent `App` component) to never execute. +**Solution:** Added a `handleSubmit` function with `e.preventDefault()` to stop the form’s default submission behavior (page reload). This allows the `onLogin(formData)` function to execute properly, which updates the `isLoggedIn` state in `App.js` and conditionally renders the welcome screen. + +--- + +## 🧪 Cypress Tests + +Cypress test file is located at: +cypress/e2e/login.cy.js + +## Cypress Test Overview + +Cypress tests were written to cover the end-to-end login flow, including: + +- Verifying that the login form renders correctly with empty inputs initially. +- Simulating user input into the name and password fields. +- Submitting the form and checking that the welcome screen appears with the correct user name. +- Testing the logout flow to ensure the app returns to the login form. + +## 🤖 AI Tool Usage + +I used **ChatGPT** to assist in generating the Cypress test cases. Specifically: + +- I provided all three components: `LoginForm.jsx`, `Welcome.jsx`, and `App.js`. +- I asked ChatGPT to create **end-to-end (E2E) test scripts** that cover the login, welcome screen, and logout flow. diff --git a/cypress/e2e/login.cy.js b/cypress/e2e/login.cy.js index c2fbb3a..d122552 100644 --- a/cypress/e2e/login.cy.js +++ b/cypress/e2e/login.cy.js @@ -1,2 +1,39 @@ -describe('Login Component', () => { -}) \ No newline at end of file +/** + * End‑to‑end tests for the basic login flow + */ +describe("Login flow", () => { + const user = { name: "admin", password: "admin" }; + + beforeEach(() => { + cy.visit("/"); + }); + + it("renders the empty form", () => { + cy.get("[data-cy=login-form]").within(() => { + cy.get('input[name="name"]').should("have.value", ""); + cy.get('input[name="password"]').should("have.value", ""); + cy.contains("Login"); + }); + }); + + it("logs in and shows the welcome screen", () => { + cy.get('input[name="name"]').type(user.name); + cy.get('input[name="password"]').type(user.password); + cy.get("[data-cy=login-submit]").click(); + + // The component‐level “redirect” is a conditional render, + // so we verify that the welcome card appears and the form disappears. + cy.contains(`Welcome, ${user.name}!`).should("be.visible"); + cy.get("[data-cy=login-form]").should("not.exist"); + }); + + it("logs out and returns to the form", () => { + // log in first + cy.get('input[name="name"]').type(user.name); + cy.get('input[name="password"]').type(user.password); + cy.get("[data-cy=login-submit]").click(); + + cy.contains("Logout").click(); + cy.get("[data-cy=login-form]").should("exist"); + }); +}); diff --git a/src/components/LoginForm.js b/src/components/LoginForm.js index 26c8cc3..895cff0 100644 --- a/src/components/LoginForm.js +++ b/src/components/LoginForm.js @@ -1,23 +1,28 @@ -import React, { useState } from 'react'; -import './LoginForm.css'; +import React, { useState } from "react"; +import "./LoginForm.css"; function LoginForm({ onLogin }) { const [formData, setFormData] = useState({ - name: '', - password: '' + name: "", + password: "", }); const handleChange = (e) => { const { name, value } = e.target; - setFormData(prevState => ({ + setFormData((prevState) => ({ ...prevState, - [name]: value + [name]: value, })); }; + const handleSubmit = (e) => { + e.preventDefault(); + onLogin(formData); + }; + return ( -
-
+
+

Login

@@ -41,7 +46,7 @@ function LoginForm({ onLogin }) { required />
- @@ -49,4 +54,4 @@ function LoginForm({ onLogin }) { ); } -export default LoginForm; \ No newline at end of file +export default LoginForm;