$
This commit is contained in:
parent
61a3513ef4
commit
7402661aaa
4
.gitignore
vendored
4
.gitignore
vendored
@ -18,3 +18,7 @@ coverage.txt
|
|||||||
/playwright-report/
|
/playwright-report/
|
||||||
/blob-report/
|
/blob-report/
|
||||||
/playwright/.cache/
|
/playwright/.cache/
|
||||||
|
/test-results/
|
||||||
|
/playwright-report/
|
||||||
|
/blob-report/
|
||||||
|
/playwright/.cache/
|
||||||
|
@ -25,6 +25,12 @@
|
|||||||
pnpm run dev
|
pnpm run dev
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Test
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
## Membre
|
## Membre
|
||||||
|
|
||||||
Bilal Boudjemline
|
Bilal Boudjemline
|
||||||
|
@ -28,11 +28,13 @@ describe("Login Component", () => {
|
|||||||
target: { value: "testuser" },
|
target: { value: "testuser" },
|
||||||
});
|
});
|
||||||
fireEvent.change(screen.getByPlaceholderText("password"), {
|
fireEvent.change(screen.getByPlaceholderText("password"), {
|
||||||
target: { value: "password123" },
|
target: { value: "Password123!!@" },
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(screen.getByPlaceholderText("username").value).toBe("testuser");
|
expect(screen.getByPlaceholderText("username").value).toBe("testuser");
|
||||||
expect(screen.getByPlaceholderText("password").value).toBe("password123");
|
expect(screen.getByPlaceholderText("password").value).toBe(
|
||||||
|
"Password123!!@",
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("handles submit event", async () => {
|
it("handles submit event", async () => {
|
||||||
@ -40,11 +42,11 @@ describe("Login Component", () => {
|
|||||||
target: { value: "testuser" },
|
target: { value: "testuser" },
|
||||||
});
|
});
|
||||||
fireEvent.change(screen.getByPlaceholderText("password"), {
|
fireEvent.change(screen.getByPlaceholderText("password"), {
|
||||||
target: { value: "password123" },
|
target: { value: "Password123!!@" },
|
||||||
});
|
});
|
||||||
fireEvent.click(screen.getByText("submit"));
|
fireEvent.click(screen.getByText("submit"));
|
||||||
|
|
||||||
expect(loginFunction).toHaveBeenCalledWith("testuser", "password123");
|
expect(loginFunction).toHaveBeenCalledWith("testuser", "Password123!!@");
|
||||||
});
|
});
|
||||||
|
|
||||||
//TODO add more tests please :)
|
//TODO add more tests please :)
|
||||||
|
@ -1,9 +0,0 @@
|
|||||||
// @ts-check
|
|
||||||
import { test, expect } from "@playwright/test";
|
|
||||||
|
|
||||||
test("has title on my project", async ({ page }) => {
|
|
||||||
await page.goto("/");
|
|
||||||
|
|
||||||
// Expect a title "to contain" a substring.
|
|
||||||
await expect(page).toHaveTitle("Vite + React");
|
|
||||||
});
|
|
22
index.html
22
index.html
@ -1,13 +1,13 @@
|
|||||||
<!doctype html>
|
<!doctype html>
|
||||||
<html lang="en">
|
<html lang="fr">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
<link rel="icon" type="image/svg+xml" href="/favico.ico" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>Vite + React</title>
|
</head>
|
||||||
</head>
|
|
||||||
<body>
|
<body>
|
||||||
<div id="root"></div>
|
<div id="root"></div>
|
||||||
<script type="module" src="/src/main.jsx"></script>
|
<script type="module" src="/src/main.jsx"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
"test": "vitest",
|
"test": "vitest",
|
||||||
"test-e2e": "npx playwright test",
|
"test-e2e": "npx playwright test",
|
||||||
"show-e2e": "npx playwright show-report",
|
"show-e2e": "npx playwright show-report",
|
||||||
|
"ui-test": "npx playwright test --ui",
|
||||||
"preview": "vite preview",
|
"preview": "vite preview",
|
||||||
"format": "prettier --write 'src/**/*.{js,jsx}'",
|
"format": "prettier --write 'src/**/*.{js,jsx}'",
|
||||||
"prepare": "husky install"
|
"prepare": "husky install"
|
||||||
@ -26,7 +27,7 @@
|
|||||||
"sass": "^1.72.0"
|
"sass": "^1.72.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@playwright/test": "^1.41.1",
|
"@playwright/test": "^1.42.1",
|
||||||
"@testing-library/react": "^14.1.2",
|
"@testing-library/react": "^14.1.2",
|
||||||
"@types/node": "^20.11.9",
|
"@types/node": "^20.11.9",
|
||||||
"@types/react": "^18.2.43",
|
"@types/react": "^18.2.43",
|
||||||
@ -43,4 +44,4 @@
|
|||||||
"vite": "^5.0.8",
|
"vite": "^5.0.8",
|
||||||
"vitest": "^1.2.2"
|
"vitest": "^1.2.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,42 +1,78 @@
|
|||||||
|
// @ts-check
|
||||||
import { defineConfig, devices } from "@playwright/test";
|
import { defineConfig, devices } from "@playwright/test";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read environment variables from file.
|
||||||
|
* https://github.com/motdotla/dotenv
|
||||||
|
*/
|
||||||
|
// require('dotenv').config();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see https://playwright.dev/docs/test-configuration
|
||||||
|
*/
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
// Look for test files in the "tests" directory, relative to this configuration file.
|
testDir: "./tests",
|
||||||
testDir: "e2e-tests",
|
/* Run tests in files in parallel */
|
||||||
|
|
||||||
// Run all tests in parallel.
|
|
||||||
fullyParallel: true,
|
fullyParallel: true,
|
||||||
|
/* Fail the build on CI if you accidentally left test.only in the source code. */
|
||||||
// Fail the build on CI if you accidentally left test.only in the source code.
|
forbidOnly: !!process.env.CI,
|
||||||
forbidOnly: !!import.meta.env.process.env.CI,
|
/* Retry on CI only */
|
||||||
|
retries: process.env.CI ? 2 : 0,
|
||||||
// Retry on CI only.
|
/* Opt out of parallel tests on CI. */
|
||||||
retries: import.meta.env.process.env.CI ? 2 : 0,
|
workers: process.env.CI ? 1 : undefined,
|
||||||
|
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
|
||||||
// Opt out of parallel tests on CI.
|
|
||||||
workers: import.meta.env.process.env.CI ? 1 : undefined,
|
|
||||||
|
|
||||||
// Reporter to use
|
|
||||||
reporter: "html",
|
reporter: "html",
|
||||||
|
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
|
||||||
use: {
|
use: {
|
||||||
// Base URL to use in actions like `await page.goto('/')`.
|
/* Base URL to use in actions like `await page.goto('/')`. */
|
||||||
baseURL: "http://localhost:5173/",
|
baseURL: "http://127.0.0.1:3000",
|
||||||
|
|
||||||
// Collect trace when retrying the failed test.
|
/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
|
||||||
trace: "on-first-retry",
|
trace: "on-first-retry",
|
||||||
},
|
},
|
||||||
// Configure projects for major browsers.
|
|
||||||
|
/* Configure projects for major browsers */
|
||||||
projects: [
|
projects: [
|
||||||
{
|
{
|
||||||
name: "chromium",
|
name: "chromium",
|
||||||
use: { ...devices["Desktop Chrome"] },
|
use: { ...devices["Desktop Chrome"] },
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// {
|
||||||
|
// name: "firefox",
|
||||||
|
// use: { ...devices["Desktop Firefox"] },
|
||||||
|
// },
|
||||||
|
|
||||||
|
// {
|
||||||
|
// name: "webkit",
|
||||||
|
// use: { ...devices["Desktop Safari"] },
|
||||||
|
// },
|
||||||
|
|
||||||
|
/* Test against mobile viewports. */
|
||||||
|
// {
|
||||||
|
// name: 'Mobile Chrome',
|
||||||
|
// use: { ...devices['Pixel 5'] },
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// name: 'Mobile Safari',
|
||||||
|
// use: { ...devices['iPhone 12'] },
|
||||||
|
// },
|
||||||
|
|
||||||
|
/* Test against branded browsers. */
|
||||||
|
// {
|
||||||
|
// name: 'Microsoft Edge',
|
||||||
|
// use: { ...devices['Desktop Edge'], channel: 'msedge' },
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// name: 'Google Chrome',
|
||||||
|
// use: { ...devices['Desktop Chrome'], channel: 'chrome' },
|
||||||
|
// },
|
||||||
],
|
],
|
||||||
// Run your local dev server before starting the tests.
|
|
||||||
|
//Run your local dev server before starting the tests /
|
||||||
webServer: {
|
webServer: {
|
||||||
command: "npm run dev",
|
command: "npm run dev",
|
||||||
url: "http://localhost:5173/",
|
url: "http://127.0.0.1:3000",
|
||||||
reuseExistingServer: !import.meta.env.process.env.CI,
|
reuseExistingServer: !process.env.CI,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
2
pnpm-lock.yaml
generated
2
pnpm-lock.yaml
generated
@ -35,7 +35,7 @@ dependencies:
|
|||||||
|
|
||||||
devDependencies:
|
devDependencies:
|
||||||
'@playwright/test':
|
'@playwright/test':
|
||||||
specifier: ^1.41.1
|
specifier: ^1.42.1
|
||||||
version: 1.42.1
|
version: 1.42.1
|
||||||
'@testing-library/react':
|
'@testing-library/react':
|
||||||
specifier: ^14.1.2
|
specifier: ^14.1.2
|
||||||
|
BIN
public/favico.ico
Normal file
BIN
public/favico.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 29 KiB |
BIN
public/favico.png
Normal file
BIN
public/favico.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 78 KiB |
@ -9,7 +9,6 @@ export default function NavBar() {
|
|||||||
const onLogout = () => {
|
const onLogout = () => {
|
||||||
logout().then((res) => {
|
logout().then((res) => {
|
||||||
if (res === "Ok") {
|
if (res === "Ok") {
|
||||||
alert("etes vous sur de vouloir quitter");
|
|
||||||
window.location.reload();
|
window.location.reload();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -1,3 +0,0 @@
|
|||||||
export default function Stats({ chart = null, datas }) {
|
|
||||||
return <div>{chart ? chart : null}</div>;
|
|
||||||
}
|
|
@ -33,22 +33,25 @@ export const AuthenticationProvider = ({ children }) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const login = async (email, password) => {
|
const login = async (email, password) => {
|
||||||
loginApi(email, password)
|
try {
|
||||||
.then((user) => {
|
const user = await loginApi(email, password);
|
||||||
setAuthState({ user });
|
setAuthState({ user });
|
||||||
redirect();
|
redirect();
|
||||||
})
|
} catch (error) {
|
||||||
.catch(() => {
|
console.error("Erreur lors de la connexion :", error);
|
||||||
console.error("ici ca catch fort");
|
setAuthState({ user: undefined });
|
||||||
setAuthState({ user: undefined });
|
}
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const register = async (username, password, confirmation) => {
|
const register = async (username, password, confirmation) => {
|
||||||
registerApi(username, password, confirmation).then((user) => {
|
try {
|
||||||
|
const user = await registerApi(username, password, confirmation);
|
||||||
setAuthState({ user });
|
setAuthState({ user });
|
||||||
redirect();
|
redirect();
|
||||||
});
|
} catch (error) {
|
||||||
|
console.error("Erreur lors de l'inscription :", error);
|
||||||
|
setAuthState({ user: undefined });
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const logout = () => {
|
const logout = () => {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
|
|
||||||
import { useAuth } from "../../hooks";
|
import { useAuth } from "../../hooks";
|
||||||
|
import { useEffect } from "react";
|
||||||
|
|
||||||
export const Login = () => {
|
export const Login = () => {
|
||||||
const { login } = useAuth();
|
const { login } = useAuth();
|
||||||
@ -9,6 +9,10 @@ export const Login = () => {
|
|||||||
const [password, setPassword] = useState("");
|
const [password, setPassword] = useState("");
|
||||||
const [error, setError] = useState();
|
const [error, setError] = useState();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
document.title = "Connexion";
|
||||||
|
}, []);
|
||||||
|
|
||||||
const onSubmit = async (e) => {
|
const onSubmit = async (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
const response = await login(username, password);
|
const response = await login(username, password);
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import React, { useState } from "react";
|
import React, { useState, useEffect } from "react";
|
||||||
|
|
||||||
import { useAuth } from "../../hooks";
|
import { useAuth } from "../../hooks";
|
||||||
|
|
||||||
@ -10,6 +10,10 @@ export const Register = () => {
|
|||||||
const [confirmation, setConfirmation] = useState("");
|
const [confirmation, setConfirmation] = useState("");
|
||||||
const [error, setError] = useState();
|
const [error, setError] = useState();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
document.title = "Inscription";
|
||||||
|
}, []);
|
||||||
|
|
||||||
const onSubmit = async (e) => {
|
const onSubmit = async (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
const response = await register(username, password, confirmation);
|
const response = await register(username, password, confirmation);
|
||||||
|
@ -4,7 +4,7 @@ import { useEffect } from "react";
|
|||||||
import { getState } from "../../api";
|
import { getState } from "../../api";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import Chart from "react-apexcharts";
|
import Chart from "react-apexcharts";
|
||||||
import "./home.scss";
|
import "./Home.scss";
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
import LoaderSpace from "../../components/LoaderSpace/LoaderSpace";
|
import LoaderSpace from "../../components/LoaderSpace/LoaderSpace";
|
||||||
|
|
||||||
@ -16,6 +16,8 @@ export const Home = () => {
|
|||||||
const [isLoad, setIsLoad] = useState(true);
|
const [isLoad, setIsLoad] = useState(true);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
document.title = "Accueil";
|
||||||
|
|
||||||
getState().then((res) => {
|
getState().then((res) => {
|
||||||
try {
|
try {
|
||||||
setIsLoad(false);
|
setIsLoad(false);
|
||||||
@ -24,6 +26,7 @@ export const Home = () => {
|
|||||||
setupRoomsStats(res.rooms);
|
setupRoomsStats(res.rooms);
|
||||||
setupGlobalStat({ years: res.years, global: res.global });
|
setupGlobalStat({ years: res.years, global: res.global });
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
window.location.href = "/login";
|
||||||
console.error(err);
|
console.error(err);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
export * from "./authenticated";
|
export * from "./authenticated";
|
||||||
export * from "./home/home";
|
export * from "./home/Home";
|
||||||
|
@ -15,11 +15,15 @@ export default function Profile() {
|
|||||||
const [confirmPassword, setConfirmPassword] = useState("");
|
const [confirmPassword, setConfirmPassword] = useState("");
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!user.user.username) {
|
document.title = `Profile`;
|
||||||
console.log("pas de login");
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const handleHelpIE = () => {
|
||||||
|
alert(
|
||||||
|
'En cliquant sur le boutton "Exporter", vous recupererez un fichier <votre_pseudo>.tascrujetaisriche qui contiendra les donnees de votre profile. Il pourra etre reutiliser sur un autre compte via le boutton "Importer"',
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
const handleUsername = (e) => {
|
const handleUsername = (e) => {
|
||||||
setUsername(e.target.value);
|
setUsername(e.target.value);
|
||||||
};
|
};
|
||||||
@ -91,7 +95,7 @@ export default function Profile() {
|
|||||||
perso_style={{
|
perso_style={{
|
||||||
width: "100px",
|
width: "100px",
|
||||||
height: "50px",
|
height: "50px",
|
||||||
background: "red",
|
background: "#ce5353",
|
||||||
fontWeight: "bold",
|
fontWeight: "bold",
|
||||||
}}
|
}}
|
||||||
handle={handleDeleteUser}
|
handle={handleDeleteUser}
|
||||||
@ -141,6 +145,24 @@ export default function Profile() {
|
|||||||
/>
|
/>
|
||||||
<StylizedBtn handle={handleSubmitPassword} text="OK" />
|
<StylizedBtn handle={handleSubmitPassword} text="OK" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div className="profile-modifier-container">
|
||||||
|
<span onClick={handleHelpIE} className="profile-modifier-title ">
|
||||||
|
Fais voyager tes depenses.
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<StylizedBtn
|
||||||
|
perso_style={{ width: "100px" }}
|
||||||
|
handle={null}
|
||||||
|
text="Exporter"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<StylizedBtn
|
||||||
|
perso_style={{ width: "100px" }}
|
||||||
|
handle={null}
|
||||||
|
text="Importer"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@ export default function Room() {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
getRoom(id).then((res) => {
|
getRoom(id).then((res) => {
|
||||||
console.log(res);
|
console.log(res);
|
||||||
|
document.title = `Piece - ${res.name}`;
|
||||||
setData(res);
|
setData(res);
|
||||||
});
|
});
|
||||||
}, []);
|
}, []);
|
||||||
|
@ -35,6 +35,8 @@ export default function Rooms() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
document.title = `Pieces`;
|
||||||
|
|
||||||
getRooms().then((res) => {
|
getRooms().then((res) => {
|
||||||
if (res.length === 0) {
|
if (res.length === 0) {
|
||||||
setIsLoad(false);
|
setIsLoad(false);
|
||||||
|
@ -8,6 +8,7 @@ import { Home, Login, Register } from "./pages";
|
|||||||
export const Router = () => (
|
export const Router = () => (
|
||||||
<Routes>
|
<Routes>
|
||||||
<Route index element={<Home />} />
|
<Route index element={<Home />} />
|
||||||
|
<Route path="home" element={<Home />} />
|
||||||
<Route path="login" element={<Login />} />
|
<Route path="login" element={<Login />} />
|
||||||
<Route path="register" element={<Register />} />
|
<Route path="register" element={<Register />} />
|
||||||
<Route path="rooms/" element={<Rooms />} />
|
<Route path="rooms/" element={<Rooms />} />
|
||||||
|
26
tests/authenticated/login.test.js
Normal file
26
tests/authenticated/login.test.js
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
// @ts-check
|
||||||
|
import { test, expect } from "@playwright/test";
|
||||||
|
import { waitFor } from "@testing-library/react";
|
||||||
|
|
||||||
|
test("Test de connexion", async ({ page }) => {
|
||||||
|
await page.goto("/login");
|
||||||
|
await page
|
||||||
|
.locator(
|
||||||
|
"#layout-container > main > div > form > input[type=text]:nth-child(1)",
|
||||||
|
)
|
||||||
|
.fill("Bilouuuuuuu94!@@");
|
||||||
|
|
||||||
|
await page
|
||||||
|
.locator(
|
||||||
|
"#layout-container > main > div > form > input[type=password]:nth-child(2)",
|
||||||
|
)
|
||||||
|
.fill("Bilouuuuuuu94!@@");
|
||||||
|
|
||||||
|
await page.locator("#layout-container > main > div > form > button").click({
|
||||||
|
button: "left",
|
||||||
|
});
|
||||||
|
|
||||||
|
await page.waitForURL("/");
|
||||||
|
const title = await page.title();
|
||||||
|
console.log(title);
|
||||||
|
});
|
Loading…
Reference in New Issue
Block a user