This commit is contained in:
@@ -0,0 +1,10 @@
|
||||
import { defineConfig } from 'cypress';
|
||||
|
||||
export default defineConfig({
|
||||
e2e: {
|
||||
baseUrl: 'http://localhost:5173',
|
||||
setupNodeEvents(on, config) {
|
||||
// implement node event listeners here
|
||||
},
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,16 @@
|
||||
// cypress/e2e/example_counter.cy.js or .cy.ts for TypeScript
|
||||
describe('ExampleCounter', () => {
|
||||
it('renders and increment the counter on click', () => {
|
||||
// Describes the individual test case
|
||||
|
||||
// 1. Visit the page where the component is rendered.
|
||||
// Change '/' to the path where your component is displayed.
|
||||
cy.visit('/');
|
||||
// 2. Check if the initial text is present.
|
||||
cy.contains('p', 'Counter: 0');
|
||||
// 3. Click on the button.
|
||||
cy.get('[data-testid="button-inc"]', { name: /Increment/i }).click();
|
||||
// 4. Check if the text has changed.
|
||||
cy.contains('p', 'Counter: 1');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"name": "Using fixtures to represent data",
|
||||
"email": "hello@cypress.io",
|
||||
"body": "Fixtures are a great way to mock data for responses to routes"
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
// ***********************************************
|
||||
// This example commands.js shows you how to
|
||||
// create various custom commands and overwrite
|
||||
// existing commands.
|
||||
//
|
||||
// For more comprehensive examples of custom
|
||||
// commands please read more here:
|
||||
// https://on.cypress.io/custom-commands
|
||||
// ***********************************************
|
||||
//
|
||||
//
|
||||
// -- This is a parent command --
|
||||
// Cypress.Commands.add('login', (email, password) => { ... })
|
||||
//
|
||||
//
|
||||
// -- This is a child command --
|
||||
// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
|
||||
//
|
||||
//
|
||||
// -- This is a dual command --
|
||||
// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
|
||||
//
|
||||
//
|
||||
// -- This will overwrite an existing command --
|
||||
// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
|
||||
@@ -0,0 +1,17 @@
|
||||
// ***********************************************************
|
||||
// This example support/e2e.js is processed and
|
||||
// loaded automatically before your test files.
|
||||
//
|
||||
// This is a great place to put global configuration and
|
||||
// behavior that modifies Cypress.
|
||||
//
|
||||
// You can change the location of this file or turn off
|
||||
// automatically serving support files with the
|
||||
// 'supportFile' configuration option.
|
||||
//
|
||||
// You can read more here:
|
||||
// https://on.cypress.io/configuration
|
||||
// ***********************************************************
|
||||
|
||||
// Import commands.js using ES2015 syntax:
|
||||
import './commands'
|
||||
+1863
-1
File diff suppressed because it is too large
Load Diff
@@ -28,6 +28,7 @@
|
||||
"@vitejs/plugin-react": "^6.2.1",
|
||||
"@vitest/ui": "^5.1.0",
|
||||
"axios-mock-adapter": "^2.1.0",
|
||||
"cypress": "^16.2.1",
|
||||
"jsdom": "^31.0.0",
|
||||
"oxlint": "^1.91.0",
|
||||
"sass-embedded": "1.107",
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import Button from './components/buttons/Button';
|
||||
import ExampleCounter from './components/examples/ExampleCounter';
|
||||
// import ExampleUserList from './components/examples/ExampleUserList';
|
||||
import FormContact from './components/forms/FormContact';
|
||||
import InputAmount from './components/inputs/InputAmount';
|
||||
import ListUser from './components/lists/ListUser';
|
||||
|
||||
function App(props) {
|
||||
@@ -10,7 +12,11 @@ function App(props) {
|
||||
<div className="container py-5">
|
||||
<h1>Testing in React</h1>
|
||||
<hr />
|
||||
<ListUser />
|
||||
<ExampleCounter />
|
||||
<hr />
|
||||
<InputAmount />
|
||||
<hr />
|
||||
{/* <ListUser /> */}
|
||||
<hr />
|
||||
<Button />
|
||||
<hr />
|
||||
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
import { useState } from 'react';
|
||||
|
||||
const ExampleCounter = () => {
|
||||
const [count, setCount] = useState(0);
|
||||
|
||||
const handleClick = () => {
|
||||
setCount(count + 1);
|
||||
};
|
||||
return (
|
||||
<div>
|
||||
<p>Counter: {count}</p>
|
||||
<button type="button" className="btn btn-dark button-inc" onClick={handleClick} data-testid="button-inc">
|
||||
Increment
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ExampleCounter;
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
import { useState } from 'react';
|
||||
import { FaPlus, FaMinus } from 'react-icons/fa6';
|
||||
|
||||
const InputAmount = () => {
|
||||
const [amount, setAmount] = useState(0);
|
||||
|
||||
const handleChange = (e) => {
|
||||
const value = e.target.value;
|
||||
if (!isNaN(value)) {
|
||||
setAmount(Number(value));
|
||||
}
|
||||
};
|
||||
|
||||
const handleClickIncrement = () => {
|
||||
setAmount(amount + 1);
|
||||
};
|
||||
|
||||
const handleClickDecrement = () => {
|
||||
setAmount(amount - 1);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="m-input-amount">
|
||||
<div className="input-group mb-3">
|
||||
<span className="input-group-text">
|
||||
<button
|
||||
type="button"
|
||||
className="btn btn-dark button-dec"
|
||||
onClick={handleClickDecrement}
|
||||
disabled={amount === 0}
|
||||
aria-label="decrease amount">
|
||||
<FaMinus />
|
||||
</button>
|
||||
</span>
|
||||
<input
|
||||
type="number"
|
||||
className="form-control input-amount"
|
||||
aria-label="Amount"
|
||||
onChange={handleChange}
|
||||
value={amount}
|
||||
/>
|
||||
<span className="input-group-text">
|
||||
<button
|
||||
type="button"
|
||||
className="btn btn-dark button-inc"
|
||||
onClick={handleClickIncrement}
|
||||
disabled={amount === 10}
|
||||
aria-label="increase amount">
|
||||
<FaPlus />
|
||||
</button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default InputAmount;
|
||||
@@ -27,7 +27,7 @@ const ListUser = (props) => {
|
||||
if (axios.isCancel(err)) {
|
||||
console.error('Request abgebrochen:', err.message);
|
||||
} else {
|
||||
console.error('Error:', err);
|
||||
// console.error('Error:', err);
|
||||
setError(err);
|
||||
}
|
||||
})
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
import { render } from '@testing-library/react';
|
||||
import InputAmount from '../components/inputs/InputAmount';
|
||||
import { describe, expect, it } from 'vitest';
|
||||
|
||||
describe('InputAmount', () => {
|
||||
it('should matches the snapshot', () => {
|
||||
const { container } = render(<InputAmount />);
|
||||
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
@@ -4,22 +4,9 @@ import { render, screen, waitFor } from '@testing-library/react';
|
||||
import axios from 'axios';
|
||||
import MockAdapter from 'axios-mock-adapter';
|
||||
import ListUser from '../components/lists/ListUser';
|
||||
import { fakeUserResponse as userResponse } from './__mocks__/userResponse.mock';
|
||||
|
||||
const USERS_API_URL = 'https://dummyjson.com/users?limit=100';
|
||||
const userResponse = {
|
||||
users: [
|
||||
{
|
||||
id: 1,
|
||||
firstName: 'John',
|
||||
lastName: 'Doe',
|
||||
age: 28,
|
||||
email: 'john.doe@example.com',
|
||||
},
|
||||
],
|
||||
total: 1,
|
||||
skip: 0,
|
||||
limit: 100,
|
||||
};
|
||||
|
||||
const mock = new MockAdapter(axios);
|
||||
|
||||
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
export const fakeUserResponse = {
|
||||
users: [
|
||||
{
|
||||
id: 1,
|
||||
firstName: 'John',
|
||||
lastName: 'Doe',
|
||||
age: 28,
|
||||
email: 'john.doe@example.com',
|
||||
},
|
||||
],
|
||||
total: 1,
|
||||
skip: 0,
|
||||
limit: 100,
|
||||
};
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
||||
|
||||
exports[`InputAmount > should matches the snapshot 1`] = `
|
||||
<div>
|
||||
<div
|
||||
class="m-input-amount"
|
||||
>
|
||||
<div
|
||||
class="input-group mb-3"
|
||||
>
|
||||
<span
|
||||
class="input-group-text"
|
||||
>
|
||||
<button
|
||||
aria-label="decrease amount"
|
||||
class="btn btn-dark button-dec"
|
||||
disabled=""
|
||||
type="button"
|
||||
>
|
||||
<svg
|
||||
fill="currentColor"
|
||||
height="1em"
|
||||
stroke="currentColor"
|
||||
stroke-width="0"
|
||||
viewBox="0 0 448 512"
|
||||
width="1em"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M432 256c0 17.7-14.3 32-32 32L48 288c-17.7 0-32-14.3-32-32s14.3-32 32-32l352 0c17.7 0 32 14.3 32 32z"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
</span>
|
||||
<input
|
||||
aria-label="Amount"
|
||||
class="form-control input-amount"
|
||||
type="number"
|
||||
value="0"
|
||||
/>
|
||||
<span
|
||||
class="input-group-text"
|
||||
>
|
||||
<button
|
||||
aria-label="increase amount"
|
||||
class="btn btn-dark button-inc"
|
||||
type="button"
|
||||
>
|
||||
<svg
|
||||
fill="currentColor"
|
||||
height="1em"
|
||||
stroke="currentColor"
|
||||
stroke-width="0"
|
||||
viewBox="0 0 448 512"
|
||||
width="1em"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M256 80c0-17.7-14.3-32-32-32s-32 14.3-32 32l0 144L48 224c-17.7 0-32 14.3-32 32s14.3 32 32 32l144 0 0 144c0 17.7 14.3 32 32 32s32-14.3 32-32l0-144 144 0c17.7 0 32-14.3 32-32s-14.3-32-32-32l-144 0 0-144z"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
Reference in New Issue
Block a user