Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .eslintignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
.eslintrc.cjs
rollup.config.mjs
rollup.config.mjs
vite.config.ts
cypress.config.ts
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [18.x]
node-version: [22.x]
steps:
- uses: actions/checkout@v3

Expand All @@ -87,4 +87,4 @@ jobs:
- run: yarn prettier-check
- run: yarn lint
- run: yarn build
- run: yarn jest
- run: yarn test
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,7 @@ storybook-static
.terraform
terraform

.npmrc
.npmrc

cypress/screenshots
cypress/videos
10 changes: 10 additions & 0 deletions 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",
},
},
});
56 changes: 56 additions & 0 deletions cypress/component/useHelloWorld.cy.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import React from "react";
import { useHelloWorld } from "../../src/lib/hooks/useHelloWorld";

// Test component that uses the hook
function TestComponent() {
useHelloWorld();
return <div data-testid="test-component">Component using useHelloWorld hook</div>;
}

describe("useHelloWorld Hook - Cypress Component Tests", () => {
it('should log "Hello World" on mount', () => {
// Create a spy on console.log before mounting
cy.window().then((win) => {
cy.spy(win.console, "log").as("consoleLog");
});

// Mount the component that uses the hook
cy.mount(<TestComponent />);

// Verify the component rendered
cy.get('[data-testid="test-component"]').should("be.visible");
cy.get('[data-testid="test-component"]').should("contain.text", "Component using useHelloWorld hook");

// Assert that console.log was called with "Hello World"
cy.get("@consoleLog").should("have.been.calledWith", "Hello World");
cy.get("@consoleLog").should("have.been.calledOnce");
});

it('should only log "Hello World" once when component re-renders', () => {
// Create a spy on console.log before mounting
cy.window().then((win) => {
cy.spy(win.console, "log").as("consoleLog");
});

// Mount the component
cy.mount(<TestComponent />);

// Force a re-render by mounting again
cy.mount(<TestComponent />);

// The console.log should still only be called once per mount
// Since we mounted twice, it should be called twice total
cy.get("@consoleLog").should("have.been.calledWith", "Hello World");
cy.get("@consoleLog").should("have.callCount", 2);
});

it("should demonstrate visual testing capabilities", () => {
cy.mount(<TestComponent />);

// Visual assertions that are unique to Cypress
cy.get('[data-testid="test-component"]').should("be.visible").and("have.css", "display");

// You could also take screenshots for visual regression testing
// cy.screenshot('useHelloWorld-component')
});
});
5 changes: 5 additions & 0 deletions cypress/fixtures/example.json
Original file line number Diff line number Diff line change
@@ -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"
}
37 changes: 37 additions & 0 deletions 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 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>
36 changes: 36 additions & 0 deletions cypress/support/component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// ***********************************************************
// This example support/component.ts 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";

import { mount } from "cypress/react";

// Augment the Cypress namespace to include type definitions for
// your custom command.
// Alternatively, can be defined in cypress/support/component.d.ts
// with a <reference path="./component" /> at the top of your spec.
declare global {
namespace Cypress {
interface Chainable {
mount: typeof mount;
}
}
}

Cypress.Commands.add("mount", mount);

// Example use:
// cy.mount(<MyComponent />)
7 changes: 6 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@
"prettier-check": "prettier --check .",
"prettier-write": "prettier --write .",
"start": "rollup -c -w",
"test": "yarn jest",
"test": "cypress run --component",
"test:all": "yarn test && yarn test:cypress",
"start-all": "concurrently \"yarn start\" \"yarn start-yalc\"",
"start-yalc": "yarn nodemon --watch dist -x \"yarn yalc push\"",
"storybook": "start-storybook -p 6006"
Expand All @@ -56,8 +57,10 @@
"@types/uuid": "^9.0.7",
"@typescript-eslint/eslint-plugin": "^5.59.2",
"@typescript-eslint/parser": "^5.59.2",
"@vitejs/plugin-react": "^5.0.2",
"concurrently": "^8.0.1",
"cross-env": "^7.0.3",
"cypress": "^15.0.0",
"eslint": "^8.45.0",
"eslint-config-prettier": "^8.8.0",
"eslint-import-resolver-typescript": "^3.5.5",
Expand All @@ -72,6 +75,7 @@
"nodemon": "^2.0.22",
"prettier": "^2.8.8",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"release-it": "^16.1.2",
"rollup": "^3.21.4",
"rollup-plugin-peer-deps-external": "^2.2.4",
Expand All @@ -80,6 +84,7 @@
"ts-jest": "^29.1.1",
"tsconfig-paths-webpack-plugin": "^4.0.1",
"typescript": "^5.1.6",
"vite": "^7.1.3",
"webpack": "^5.82.0",
"yalc": "^1.0.0-pre.53"
},
Expand Down
11 changes: 11 additions & 0 deletions vite.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";

export default defineConfig({
plugins: [react()],
resolve: {
alias: {
"@": "/src",
},
},
});
Loading
Loading