This commit is contained in:
pro.boooooo 2024-04-01 12:55:40 +02:00
parent 61a3513ef4
commit 7402661aaa
22 changed files with 175 additions and 73 deletions

4
.gitignore vendored
View File

@ -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/

View File

@ -25,6 +25,12 @@
pnpm run dev pnpm run dev
``` ```
### Test
```
```
## Membre ## Membre
Bilal Boudjemline Bilal Boudjemline

View File

@ -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 :)

View File

@ -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");
});

View File

@ -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>

View File

@ -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",

View File

@ -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
View File

@ -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

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

BIN
public/favico.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

View File

@ -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();
} }
}); });

View File

@ -1,3 +0,0 @@
export default function Stats({ chart = null, datas }) {
return <div>{chart ? chart : null}</div>;
}

View File

@ -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 = () => {

View File

@ -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);

View File

@ -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);

View File

@ -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);
} }
}); });

View File

@ -1,2 +1,2 @@
export * from "./authenticated"; export * from "./authenticated";
export * from "./home/home"; export * from "./home/Home";

View File

@ -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>
); );
} }

View File

@ -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);
}); });
}, []); }, []);

View File

@ -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);

View File

@ -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 />} />

View 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);
});