use cypress for integration tests

This commit is contained in:
Elio Bischof
2023-06-05 23:27:05 +02:00
parent d312c86ac0
commit 24c1ed7dca
17 changed files with 972 additions and 343 deletions

View File

@@ -1,5 +1,5 @@
import { render, screen, waitFor, within } from '@testing-library/react';
import PasswordComplexity from './PasswordComplexity';
import PasswordComplexity from '../ui/PasswordComplexity';
// TODO: Why does this not compile?
// import { ResourceOwnerType } from '@zitadel/server';

View File

@@ -0,0 +1,11 @@
{
"extends": "../tsconfig.json",
"compilerOptions": {
"jsx": "react-jsxdev",
"types": [
"node",
"jest",
"@testing-library/jest-dom"
]
}
}

View File

@@ -0,0 +1,11 @@
import { defineConfig } from "cypress";
export default defineConfig({
reporter: 'dot',
e2e: {
specPattern: 'cypress/integration/**/*.cy.{js,jsx,ts,tsx}',
setupNodeEvents(on, config) {
// implement node event listeners here
},
},
});

View File

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

View File

@@ -0,0 +1,3 @@
describe('integration', () => {
it('transpiling works with jest and cypress together', () => {})
})

View File

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

View File

@@ -0,0 +1,20 @@
// ***********************************************************
// This example support/e2e.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'
// Alternatively you can use CommonJS syntax:
// require('./commands')

View File

@@ -0,0 +1,8 @@
{
"extends": "../tsconfig.json",
"compilerOptions": {
"types": [
"cypress"
]
}
}

Binary file not shown.

View File

@@ -1,17 +1,22 @@
import type { Config } from '@jest/types';
import { pathsToModuleNameMapper } from 'ts-jest'
import { compilerOptions } from './tsconfig.json';
export default async (): Promise<Config.InitialOptions> => {
return {
preset: 'ts-jest',
transform: {
"^.+\\.tsx?$": ['ts-jest', { tsconfig: 'tsconfig.test.json' }],
"^.+\\.tsx?$": ['ts-jest', {tsconfig:'./__test__/tsconfig.json'}],
},
setupFilesAfterEnv: [
'@testing-library/jest-dom/extend-expect',
],
moduleNameMapper: {
'^#/(.*)$': '<rootDir>/$1',
},
moduleNameMapper: pathsToModuleNameMapper(compilerOptions.paths, {
prefix:'<rootDir>/'
}),
testEnvironment: 'jsdom',
testRegex: '/__test__/.*\\.test\\.tsx?$',
modulePathIgnorePatterns: ['cypress'],
reporters: [[ 'jest-silent-reporter', { useDots: true, showWarnings: true, showPaths: true } ]]
};
};

View File

@@ -1,6 +0,0 @@
import { mockLoginBackend } from './mock-login-backend';
mockLoginBackend.printHandlers()
mockLoginBackend.listen()
console.log("listened")

View File

@@ -1,27 +0,0 @@
// Inspired by https://kentcdodds.com/blog/stop-mocking-fetch
// These handlers simulate the login backend
// They are used in tests and for local development
import {DefaultBodyType, PathParams, ResponseComposition, RestContext, RestRequest, rest} from 'msw'
import {setupServer} from 'msw/node'
const handlers = [
rest.post('/verifyemail', async (req, res, ctx) => {
// checkAuthorized(req,res,ctx)
return res(ctx.json({
sequence: 111,
changeDate: "2023-01-01T00:00:00.000Z",
resourceOwner: "111111111111111111"
}))
}),
]
const checkAuthorized = (req: RestRequest<DefaultBodyType, PathParams<string>>, res: ResponseComposition<DefaultBodyType>, ctx: RestContext) => {
if (!req.headers.has('Authorization')){
const err = "Not authorized"
res(ctx.status(401), ctx.json({message: err}))
throw err
}
}
const mockLoginBackend = setupServer(...handlers)
export {mockLoginBackend, rest}

View File

@@ -2,13 +2,20 @@
"name": "@zitadel/login",
"private": true,
"scripts": {
"test": "jest",
"test:watch": "jest --watch",
"build": "next build",
"dev": "next dev",
"test": "concurrently --kill-others-on-fail 'npm:test:unit' 'npm:test:integration'",
"test:watch": "concurrently --kill-others 'npm:test:unit:watch' 'npm:test:integration:watch'",
"test:unit": "jest",
"test:unit:watch": "jest --watch",
"test:integration": "start-server-and-test dev http://localhost:3000 \"test:integration:run\"",
"test:integration:watch": "start-server-and-test dev http://localhost:3000 \"pnpm nodemon --verbose -e js,jsx,ts,tsx,css,scss --ignore \\\"__test__/**\\\" --exec \\\"pnpm run test:integration:run\\\"\"",
"test:integration:run": "cypress run --quiet",
"test:integration:open": "cypress open",
"lint": "next lint && prettier --check .",
"lint:fix": "prettier --write .",
"lint-staged": "lint-staged",
"build": "next build",
"prestart": "build",
"start": "next start",
"clean": "rm -rf .turbo && rm -rf node_modules && rm -rf .next",
"storybook": "storybook dev -p 6006",
@@ -68,6 +75,8 @@
"@vercel/git-hooks": "1.0.0",
"@zitadel/tsconfig": "workspace:*",
"autoprefixer": "10.4.13",
"concurrently": "^8.1.0",
"cypress": "^12.13.0",
"del-cli": "5.0.0",
"eslint-config-zitadel": "workspace:*",
"eslint-plugin-storybook": "^0.6.12",
@@ -75,19 +84,21 @@
"jest": "^29.5.0",
"jest-environment-jsdom": "^29.5.0",
"jest-fetch-mock": "^3.0.3",
"jest-silent-reporter": "^0.5.0",
"lint-staged": "13.0.3",
"make-dir-cli": "3.0.0",
"msw": "^1.2.1",
"next-router-mock": "^0.9.3",
"nodemon": "^2.0.22",
"postcss": "8.4.21",
"prettier-plugin-tailwindcss": "0.1.13",
"start-server-and-test": "^2.0.0",
"storybook": "^7.0.18",
"storybook-css-modules-preset": "^1.1.1",
"tailwindcss": "3.2.4",
"ts-jest": "^29.1.0",
"ts-node": "^10.9.1",
"ts-proto": "^1.139.0",
"typescript": "4.8.4",
"typescript": "5.0.4",
"whatwg-fetch": "^3.6.2",
"zitadel-tailwind-config": "workspace:*"
}

View File

@@ -1,12 +1,29 @@
{
"extends": "@zitadel/tsconfig/nextjs.json",
"compilerOptions": {
"jsx": "preserve",
"rootDir": ".",
"baseUrl": ".",
"paths": {
"#/*": ["./*"]
"#/*": [
"./*"
]
},
"plugins": [{ "name": "next" }]
"plugins": [
{
"name": "next"
}
]
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
"exclude": ["node_modules"]
}
"include": [
"next-env.d.ts",
"**/*.ts",
"**/*.tsx",
".next/types/**/*.ts"
],
"exclude": [
"cypress",
"cypress.config.ts",
"node_modules"
]
}

View File

@@ -1,6 +0,0 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"jsx": "react-jsx"
},
}

View File

@@ -0,0 +1,5 @@
describe('slug', () => {
it('this is not a real test', () => { })
})
export { }

1113
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff