From 03c2f321c42e61bc66608d72fb2602c93ec44cd0 Mon Sep 17 00:00:00 2001
From: Tamir Abutbul <1tamir198@gmail.com>
Date: Tue, 9 Jan 2024 10:05:43 +0200
Subject: [PATCH] Adding cypress + example test (#476)
---
frontend/cypress.config.ts | 10 +++++
frontend/cypress/support/commands.ts | 37 +++++++++++++++++++
frontend/cypress/support/component-index.html | 12 ++++++
frontend/cypress/support/component.ts | 12 ++++++
frontend/package.json | 5 ++-
frontend/src/components/Button.cy.tsx | 31 ++++++++++++++++
frontend/src/components/TextInput.cy.tsx | 26 +++++++++++++
frontend/tsconfig.json | 11 +++++-
8 files changed, 141 insertions(+), 3 deletions(-)
create mode 100644 frontend/cypress.config.ts
create mode 100644 frontend/cypress/support/commands.ts
create mode 100644 frontend/cypress/support/component-index.html
create mode 100644 frontend/cypress/support/component.ts
create mode 100644 frontend/src/components/Button.cy.tsx
create mode 100644 frontend/src/components/TextInput.cy.tsx
diff --git a/frontend/cypress.config.ts b/frontend/cypress.config.ts
new file mode 100644
index 0000000..5b8a83b
--- /dev/null
+++ b/frontend/cypress.config.ts
@@ -0,0 +1,10 @@
+import { defineConfig } from "cypress";
+
+export default defineConfig({
+ component: {
+ devServer: {
+ framework: "react",
+ bundler: "vite",
+ },
+ },
+});
\ No newline at end of file
diff --git a/frontend/cypress/support/commands.ts b/frontend/cypress/support/commands.ts
new file mode 100644
index 0000000..698b01a
--- /dev/null
+++ b/frontend/cypress/support/commands.ts
@@ -0,0 +1,37 @@
+///
+// ***********************************************
+// 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
+// drag(subject: string, options?: Partial): Chainable
+// dismiss(subject: string, options?: Partial): Chainable
+// visit(originalFn: CommandOriginalFn, url: string, options: Partial): Chainable
+// }
+// }
+// }
\ No newline at end of file
diff --git a/frontend/cypress/support/component-index.html b/frontend/cypress/support/component-index.html
new file mode 100644
index 0000000..ac6e79f
--- /dev/null
+++ b/frontend/cypress/support/component-index.html
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+ Components App
+
+
+
+
+
\ No newline at end of file
diff --git a/frontend/cypress/support/component.ts b/frontend/cypress/support/component.ts
new file mode 100644
index 0000000..f1ad5ea
--- /dev/null
+++ b/frontend/cypress/support/component.ts
@@ -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);
\ No newline at end of file
diff --git a/frontend/package.json b/frontend/package.json
index 322a282..7ba589d 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -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",
@@ -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": "",
diff --git a/frontend/src/components/Button.cy.tsx b/frontend/src/components/Button.cy.tsx
new file mode 100644
index 0000000..875412c
--- /dev/null
+++ b/frontend/src/components/Button.cy.tsx
@@ -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();
+ cy.get("button").should("exist");
+ });
+
+ it("Should have correct text", () => {
+ mount();
+ cy.get("button").contains(buttonText);
+ });
+
+ it("calls onClick when clicked", () => {
+ const onClickStub = cy.stub().as("onClick");
+
+ mount();
+
+ cy.get("button").click();
+ cy.get("@onClick").should("have.been.calledOnce");
+ });
+
+ it("should be disabled", () => {
+ mount();
+
+ cy.get("button").should("be.disabled");
+ });
+});
diff --git a/frontend/src/components/TextInput.cy.tsx b/frontend/src/components/TextInput.cy.tsx
new file mode 100644
index 0000000..6bc9ca4
--- /dev/null
+++ b/frontend/src/components/TextInput.cy.tsx
@@ -0,0 +1,26 @@
+import TextInput from "../components/TextInput";
+
+describe("TextInput", () => {
+ const label = "label";
+ const placeholder = "some placeholder";
+
+ beforeEach(() => {
+ cy.mount(
+ {
+ return;
+ }}
+ />
+ );
+ });
+
+ it("contains correct label", () => {
+ cy.get("label").should("contain", label);
+ });
+
+ it("contains correct placeholder", () => {
+ cy.get("input").should("have.attr", "placeholder", placeholder);
+ });
+});
diff --git a/frontend/tsconfig.json b/frontend/tsconfig.json
index ef3632d..1deabe3 100644
--- a/frontend/tsconfig.json
+++ b/frontend/tsconfig.json
@@ -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" }]
}