Skip to content
10 changes: 10 additions & 0 deletions frontend/cypress.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { defineConfig } from "cypress";

export default defineConfig({
component: {
devServer: {
framework: "react",
bundler: "vite",
},
},
});
37 changes: 37 additions & 0 deletions frontend/cypress/support/commands.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/// <reference types="cypress" />
// ***********************************************
// This example commands.ts 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) => { ... })
//
// declare global {
// namespace Cypress {
// interface Chainable {
// login(email: string, password: string): Chainable<void>
// drag(subject: string, options?: Partial<TypeOptions>): Chainable<Element>
// dismiss(subject: string, options?: Partial<TypeOptions>): Chainable<Element>
// visit(originalFn: CommandOriginalFn, url: string, options: Partial<VisitOptions>): Chainable<Element>
// }
// }
// }
12 changes: 12 additions & 0 deletions frontend/cypress/support/component-index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>Components App</title>
</head>
<body>
<div data-cy-root></div>
</body>
</html>
12 changes: 12 additions & 0 deletions frontend/cypress/support/component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import "./commands";
import { mount } from "cypress/react18";

declare global {
namespace Cypress {
interface Chainable {
mount: typeof mount;
}
}
}

Cypress.Commands.add("mount", mount);
5 changes: 4 additions & 1 deletion frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
"@typescript-eslint/parser": "^6.2.1",
"@vitejs/plugin-react": "^3.1.0",
"autoprefixer": "^10.4.14",
"cypress": "^13.3.0",
"eslint": "^8.46.0",
"eslint-config-prettier": "^8.7.0",
"eslint-plugin-react": "^7.33.1",
Expand Down Expand Up @@ -75,7 +76,9 @@
"lint": "npx eslint src/",
"lint:fix": "npm run lint -- --fix",
"prettier": "npx prettier src/ --check",
"prettier:fix": "npm run prettier -- --write"
"prettier:fix": "npm run prettier -- --write",
"cypress:open": "cypress open",
"cypress:run": "cypress run"
},
"keywords": [],
"author": "",
Expand Down
31 changes: 31 additions & 0 deletions frontend/src/components/Button.cy.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { mount } from "cypress/react18";
import { Button } from "./common/Button/Button";

describe("Button component tests", () => {
const buttonText = "buttonText";

it("renders", () => {
mount(<Button onClick={() => {}}></Button>);
cy.get("button").should("exist");
});

it("Should have correct text", () => {
mount(<Button label={buttonText} onClick={() => {}}></Button>);
cy.get("button").contains(buttonText);
});

it("calls onClick when clicked", () => {
const onClickStub = cy.stub().as("onClick");

mount(<Button onClick={onClickStub}></Button>);

cy.get("button").click();
cy.get("@onClick").should("have.been.calledOnce");
});

it("should be disabled", () => {
mount(<Button onClick={() => {}} disabled></Button>);

cy.get("button").should("be.disabled");
});
});
26 changes: 26 additions & 0 deletions frontend/src/components/TextInput.cy.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import TextInput from "../components/TextInput";

describe("TextInput", () => {
const label = "label";
const placeholder = "some placeholder";

beforeEach(() => {
cy.mount(
<TextInput
label={label}
placeholder={placeholder}
onChange={() => {
return;
}}
/>
);
});

it("contains correct label", () => {
cy.get("label").should("contain", label);
});

it("contains correct placeholder", () => {
cy.get("input").should("have.attr", "placeholder", placeholder);
});
});
11 changes: 9 additions & 2 deletions frontend/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,15 @@
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx"
"jsx": "react-jsx",
"types": ["cypress"]
},
"include": ["src", "public/static", ".storybook/**/*.ts", "public/analytics.js"],
"include": [
"src",
"public/static",
".storybook/**/*.ts",
"public/analytics.js",
"cypress"
],
"references": [{ "path": "./tsconfig.node.json" }]
}