Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Progress for Task 29 (Plus Additional Features and Error Handling) #20

Merged
merged 48 commits into from
Dec 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
77a01af
Update to set up playwright
dylandunsheath Dec 3, 2024
1123d1e
Progress for register test playwright
dylandunsheath Dec 3, 2024
4def6d2
Concurrently update for frontend and backend
dylandunsheath Dec 3, 2024
364fa82
Progress for registration testing e2e
dylandunsheath Dec 3, 2024
c2dff36
Update for e2e registration
dylandunsheath Dec 3, 2024
837dd93
Progress for login E2E playwright
dylandunsheath Dec 3, 2024
22793e7
Update to login.spec.ts - remove unused import
dylandunsheath Dec 3, 2024
9e3a4ad
Update for register and email tests
dylandunsheath Dec 4, 2024
647fb32
Update to ensure tests pass (email already registered) for registrati…
dylandunsheath Dec 4, 2024
f097f9b
Hide test-results for playwright
dylandunsheath Dec 4, 2024
3f27fe9
Update to hide tests results in frontend FIX
dylandunsheath Dec 4, 2024
9fb4bef
Remove folder_name from repository
dylandunsheath Dec 4, 2024
e3db328
Stop tracking test-results/ folder and update .gitignore
dylandunsheath Dec 4, 2024
022623e
Progress for form.spec.ts
dylandunsheath Dec 5, 2024
b2a02d2
Update: Progress for form testing E2E
dylandunsheath Dec 7, 2024
c50d3e8
Update comment in playwright config
dylandunsheath Dec 7, 2024
5f6baaa
Update: Job Description Test - Exceeds Max Length
dylandunsheath Dec 7, 2024
7be3cc5
Update: Part of successful description done
dylandunsheath Dec 7, 2024
26d295c
Update for login failure test
dylandunsheath Dec 7, 2024
f951ac3
Update: Add one test in playwright for registration and login
dylandunsheath Dec 7, 2024
c70864a
Update package.json backend
dylandunsheath Dec 7, 2024
f882eed
Update form.spec.ts: login then go to form
dylandunsheath Dec 7, 2024
ad01114
Update: Include dashboard.spec.ts
dylandunsheath Dec 9, 2024
b166bde
Update: Include dashboard.spec.ts
dylandunsheath Dec 9, 2024
cd0fa52
Update: Set-up dashboard.spec.ts
dylandunsheath Dec 9, 2024
27b4ddf
Update: playwright config file
dylandunsheath Dec 9, 2024
60aebe3
Update: dashboard.spec.ts test.describe change
dylandunsheath Dec 9, 2024
522e250
Update: registration and login error check
dylandunsheath Dec 10, 2024
f5554f3
Update: Halt registration success before login
dylandunsheath Dec 10, 2024
be30b07
Update: registration.tsx halt to login
dylandunsheath Dec 10, 2024
d8c7f43
Update: Login email validation
dylandunsheath Dec 10, 2024
4e00b6b
Update: Login and registration
dylandunsheath Dec 10, 2024
15c89f7
Update registration
dylandunsheath Dec 10, 2024
803384e
Update: Fix issue with passowrd error replacement registration
dylandunsheath Dec 10, 2024
d1e03ea
Update: register and job description update
dylandunsheath Dec 10, 2024
828807c
Comment out dashboard page temporary
dylandunsheath Dec 10, 2024
88d2282
fix tests
AlaraBread Dec 14, 2024
a7878be
fix formatting
AlaraBread Dec 14, 2024
74202f3
update workflow to install playwright
AlaraBread Dec 14, 2024
4472adf
Merge pull request #1 from dylandunsheath/dev
dylandunsheath Dec 14, 2024
cf46691
Update: More tests within e2e/tests/ directory
dylandunsheath Dec 14, 2024
3e55887
Update: Include file name when selected
dylandunsheath Dec 14, 2024
ab602fe
Update: test to display filename in form.spec.ts
dylandunsheath Dec 14, 2024
5ab5593
Update: Test for > 2 MB File
dylandunsheath Dec 14, 2024
83e87c9
Update: No resume submitted error
dylandunsheath Dec 14, 2024
11faca2
Update: Edit dashboard.spec.ts
dylandunsheath Dec 15, 2024
328e2a0
merge
AlaraBread Dec 16, 2024
ac680f7
finish testing
AlaraBread Dec 16, 2024
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: 2 additions & 0 deletions .github/workflows/node.js.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,7 @@ jobs:
run: cd frontend; npm run lint
- name: nextjs build
run: cd frontend; npm run build
- name: install playwright
run: npx playwright install --with-deps
- name: run tests
run: cd frontend; npm run test:ci
2 changes: 1 addition & 1 deletion backend/api/login/login.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ async function login(ctx: Context) {

const hashedPassword = await generateHash(email, password);

if (user.email !== email || user.password !== hashedPassword) {
if (!user || user.password !== hashedPassword) {
ctx.response.status = 401;
ctx.response.body = JSON.stringify({
isError: true,
Expand Down
13 changes: 12 additions & 1 deletion docs/SETUP.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ The frontend is in `/frontend`. It is a [next.js](https://nextjs.org/) project t
3. ```sh
npm install
```
4. to setup end to end testing, run
```sh
npx playwright install --with-deps
```

### Formatting

Expand Down Expand Up @@ -55,6 +59,13 @@ To run the same checks that run in ci on your local, you can run
npm run check
```

### Run end to end tests

(in `frontend`)
```sh
npm run test:e2e
```

## Backend

The backend is in `/backend`. It is an [oak server](https://oakserver.org/) that uses [deno](https://deno.com/).
Expand Down Expand Up @@ -96,7 +107,7 @@ The backend is in `/backend`. It is an [oak server](https://oakserver.org/) that

**Step 4.4:** Copy the generated secret key.

**Step 4.5:** Add the secret key to your `local.env` file as an environment variable. Use the following format:
**Step 4.5:** Add the secret key to your `backend/local.env` file as an environment variable. Use the following format:
```env
OPENAI_API_KEY=your-token-key
```
Expand Down
3 changes: 3 additions & 0 deletions frontend/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,6 @@ yarn-error.log*
# typescript
*.tsbuildinfo
next-env.d.ts

# Ignore the test-results folder
/test-results/
14 changes: 8 additions & 6 deletions frontend/app/form/job_description_form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,7 @@ export default function JobDescriptionForm(props: { onSubmit?: () => void }) {
<Card>
<CardHeader title="Job Description" />
<CardContent>
<form
onSubmit={(event) => {
void handleSubmit(event);
}}
>
<form onSubmit={handleSubmit}>
{isLoading ? <CircularProgress /> : undefined}
<TextField
label="Job Description"
Expand All @@ -68,7 +64,13 @@ export default function JobDescriptionForm(props: { onSubmit?: () => void }) {
margin="normal"
/>
Character count: {description.length}/5000
<Button type="submit" variant="contained" fullWidth>
<Button
type="submit"
variant="contained"
fullWidth
disabled={isLoading}
data-testid="submit-button"
>
Submit Job Description
</Button>
{message ?? ""}
Expand Down
18 changes: 17 additions & 1 deletion frontend/app/form/resume_form.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"use client";

import { useState } from "react";
import React, { useState } from "react";
import { backendFormPost } from "util/fetching";
import {
Button,
Expand All @@ -9,6 +9,7 @@ import {
CardHeader,
CircularProgress,
styled,
Typography,
} from "@mui/material";

/*https://mui.com/material-ui/react-button/#file-upload*/
Expand All @@ -27,6 +28,12 @@ const VisuallyHiddenInput = styled("input")({
export default function ResumeForm(props: { onSubmit?: () => void }) {
const [message, setMessage] = useState<string | null>(null);
const [isLoading, setLoading] = useState(false);
const [selectedFile, setSelectedFile] = useState<File | null>(null);

const handleFileChange = (event: React.ChangeEvent<HTMLInputElement>) => {
const file = event.target.files?.[0] || null;
setSelectedFile(file);
};

const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
Expand Down Expand Up @@ -84,8 +91,17 @@ export default function ResumeForm(props: { onSubmit?: () => void }) {
name="file"
type="file"
accept="application/pdf"
onChange={handleFileChange}
/>
</Button>
{selectedFile && (
<Typography
variant="body2"
style={{ marginTop: "0.5rem" }}
>
Selected File: {selectedFile.name}
</Typography>
)}
<Button
type="submit"
variant="contained"
Expand Down
31 changes: 27 additions & 4 deletions frontend/app/login/login.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { backendPost } from "util/fetching";
export function Login() {
const [postData, setPostData] = useState<string | undefined>();
const [blankMessage, setBlankMessage] = useState("");
const [emailMessage, setEmailMessage] = useState("");
const [isLoading, setLoading] = useState(false);
const router = useRouter();
function onSubmit(event: FormEvent) {
Expand All @@ -24,13 +25,25 @@ export function Login() {
const email = data.get("email")?.toString() ?? "";
const password = data.get("password")?.toString() ?? "";

setBlankMessage("");
setEmailMessage("");

if (!email || !password) {
setBlankMessage(
"Please make sure you didn't leave any of the fields blank.",
);
return;
}
setBlankMessage("");

// verify email format
const emailRegex = /^.+@.+$/;
if (!emailRegex.test(email)) {
setEmailMessage(
"Please enter a valid email address for logging in.",
);
return;
}

setLoading(true);

//input is valid
Expand All @@ -40,8 +53,14 @@ export function Login() {
})
.then((data) => {
setLoading(false);
setPostData(data.message);
router.push("/form");
if (data.isError) {
setLoading(false);
// Show error and stay on login
setPostData(data.message);
} else {
setPostData(data.message);
router.push("/form");
}
})
.catch((reason) => {
setLoading(false);
Expand All @@ -53,7 +72,9 @@ export function Login() {
<CardHeader component="h2" title="Login" />
{isLoading ? <CircularProgress /> : undefined}
<CardContent>
<p data-testid="backend-login-post">{postData}</p>
<p data-testid="backend-login-post">
{!blankMessage && !emailMessage ? postData : ""}
</p>
<form encType="text/plain" onSubmit={onSubmit}>
<Input name="email" placeholder="email" />
<br />
Expand All @@ -66,6 +87,8 @@ export function Login() {
{/* will let the user know when that fields cannot be left blank*/}
<span data-testid="blank-message">{blankMessage}</span>
<br />
<span data-testid="email-message">{emailMessage}</span>
<br />
<Button variant="contained" type="submit">
login
</Button>
Expand Down
36 changes: 31 additions & 5 deletions frontend/app/register/register.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { backendPost } from "util/fetching";
export function Register() {
const [postData, setPostData] = useState<string | undefined>();
const [blankMessage, setBlankMessage] = useState("");
const [emailMessage, setEmailMessage] = useState("");
const [passMessage, setPassMessage] = useState("");
const [isLoading, setLoading] = useState(false);
const router = useRouter();
Expand All @@ -27,22 +28,33 @@ export function Register() {
const password = data.get("password")?.toString() ?? "";
const confirmPassword = data.get("confirm_password")?.toString() ?? "";

setBlankMessage("");
setEmailMessage("");
setPassMessage("");
// verify fields are not empty
if (!email || !username || !password || !confirmPassword) {
setBlankMessage(
"Please make sure you didn't leave any of the fields blank.",
);
return;
}
setBlankMessage("");

//setBlankMessage("");
// verify email format
const emailRegex = /^[a-zA-Z0-9_]+@[a-zA-Z]+\.[a-z]{2,}$/;
if (!emailRegex.test(email)) {
setEmailMessage("Please enter a valid email address.");
return;
}

//setEmailMessage("");
// verify passwords match
if (password != confirmPassword) {
setPassMessage("Please make sure passwords match.");
return;
}
setPassMessage("");

//setPassMessage("");
// input is valid
setLoading(true);
backendPost("api/register", {
Expand All @@ -51,22 +63,32 @@ export function Register() {
password,
})
.then((data) => {
setPostData(data.message);
setLoading(false);
router.push("/login");
if (data.isError) {
setLoading(false);
setPostData(data.message);
} else {
setPostData(data.message);
router.push("/login");
}
})
.catch((reason) => {
console.error(reason);
setPostData("Error: " + (reason?.message ?? reason));
setLoading(false);
});
}

return (
<Card>
<CardHeader component="h2" title="Register" />
{isLoading ? <CircularProgress /> : undefined}
<CardContent>
<p data-testid="backend-register-post">{postData}</p>
<p data-testid="backend-register-post">
{!blankMessage && !emailMessage && !passMessage
? postData
: ""}
</p>
<form encType="text/plain" onSubmit={onSubmit}>
<Input name="email" placeholder="email" />
<br />
Expand All @@ -83,12 +105,16 @@ export function Register() {
type="password"
placeholder="confirm password"
/>
<br />
{/* will let the user know when the passwords dont match*/}
<span data-testid="pass-message">{passMessage}</span>
<br />
{/* will let the user know when that fields cannot be left blank*/}
<span data-testid="blank-message">{blankMessage}</span>
<br />
{/* will let the user know when that fields cannot be left blank*/}
<span data-testid="email-message">{emailMessage}</span>
<br />
<Button variant="contained" type="submit">
register
</Button>
Expand Down
15 changes: 15 additions & 0 deletions frontend/e2e/playwright.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { defineConfig } from "@playwright/test";

export default defineConfig({
testDir: "./tests", // Test directory
timeout: 20000, // Timeout for each test
use: {
baseURL: "http://localhost:3000", // Base URL for app
headless: true, // Run in headless mode
},
webServer: {
command: "npm run dev",
url: "http://localhost:3000",
reuseExistingServer: true,
},
});
Loading
Loading