add playwright for e2e testing (#873)
This commit is contained in:
		
							parent
							
								
									c62e1a0eeb
								
							
						
					
					
						commit
						a9ee2ef9ae
					
				
					 10 changed files with 777 additions and 54 deletions
				
			
		
							
								
								
									
										3
									
								
								.github/workflows/e2e.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.github/workflows/e2e.yml
									
									
									
									
										vendored
									
									
								
							|  | @ -60,6 +60,8 @@ jobs: | ||||||
|       - run: yarn start & |       - run: yarn start & | ||||||
|       - run: npx wait-port 3000 --timeout 10000 |       - run: npx wait-port 3000 --timeout 10000 | ||||||
|       - run: yarn cypress run |       - run: yarn cypress run | ||||||
|  |       - run: yarn playwright install-deps | ||||||
|  |       - run: yarn test-playwright | ||||||
| 
 | 
 | ||||||
|       - name: Upload videos |       - name: Upload videos | ||||||
|         if: ${{ always() }} |         if: ${{ always() }} | ||||||
|  | @ -69,3 +71,4 @@ jobs: | ||||||
|           path: | |           path: | | ||||||
|             cypress/videos |             cypress/videos | ||||||
|             cypress/screenshots |             cypress/screenshots | ||||||
|  |             playwright/screenshots | ||||||
|  |  | ||||||
							
								
								
									
										8
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										8
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							|  | @ -11,6 +11,11 @@ | ||||||
| 
 | 
 | ||||||
| # testing | # testing | ||||||
| /coverage | /coverage | ||||||
|  | .nyc_output | ||||||
|  | cypress/videos | ||||||
|  | cypress/screenshots | ||||||
|  | playwright/videos | ||||||
|  | playwright/screenshots | ||||||
| 
 | 
 | ||||||
| # next.js | # next.js | ||||||
| /.next/ | /.next/ | ||||||
|  | @ -51,6 +56,3 @@ yarn-error.log* | ||||||
| # Local History for Visual Studio Code | # Local History for Visual Studio Code | ||||||
| .history/ | .history/ | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| cypress/videos |  | ||||||
| cypress/screenshots |  | ||||||
|  |  | ||||||
							
								
								
									
										12
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								README.md
									
									
									
									
									
								
							|  | @ -82,8 +82,9 @@ Here is what you need to be able to run Cal. | ||||||
| 
 | 
 | ||||||
| You will also need Google API credentials. You can get this from the [Google API Console](https://console.cloud.google.com/apis/dashboard). More details on this can be found below under the [Obtaining the Google API Credentials section](#Obtaining-the-Google-API-Credentials). | You will also need Google API credentials. You can get this from the [Google API Console](https://console.cloud.google.com/apis/dashboard). More details on this can be found below under the [Obtaining the Google API Credentials section](#Obtaining-the-Google-API-Credentials). | ||||||
| 
 | 
 | ||||||
| ### Development Setup | ## Development | ||||||
| 
 | 
 | ||||||
|  | ### Setup | ||||||
| #### Quick start with `yarn dx` | #### Quick start with `yarn dx` | ||||||
| 
 | 
 | ||||||
| > - **Requires Docker to be installed** | > - **Requires Docker to be installed** | ||||||
|  | @ -158,6 +159,15 @@ yarn dx | ||||||
| 10. Open a browser to [http://localhost:3000](http://localhost:3000) and login with your just created, first user. | 10. Open a browser to [http://localhost:3000](http://localhost:3000) and login with your just created, first user. | ||||||
| 11. Set a 32 character random string in your .env file for the CALENDSO_ENCRYPTION_KEY. | 11. Set a 32 character random string in your .env file for the CALENDSO_ENCRYPTION_KEY. | ||||||
| 
 | 
 | ||||||
|  | #### E2E-Testing | ||||||
|  | 
 | ||||||
|  | ```bash | ||||||
|  | # In first terminal | ||||||
|  | yarn dev  | ||||||
|  | # In second terminal | ||||||
|  | yarn test-playwright | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
| ### Upgrading from earlier versions | ### Upgrading from earlier versions | ||||||
| 
 | 
 | ||||||
| 1. Pull the current version: | 1. Pull the current version: | ||||||
|  |  | ||||||
							
								
								
									
										19
									
								
								jest.config.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								jest.config.ts
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,19 @@ | ||||||
|  | import type { Config } from "@jest/types"; | ||||||
|  | 
 | ||||||
|  | const config: Config.InitialOptions = { | ||||||
|  |   verbose: true, | ||||||
|  |   roots: ["<rootDir>"], | ||||||
|  |   testMatch: ["**/tests/**/*.+(ts|tsx|js)", "**/?(*.)+(spec|test).+(ts|tsx|js)"], | ||||||
|  |   testPathIgnorePatterns: ["<rootDir>/.next", "<rootDir>/playwright/", "<rootDir>/cypress/"], | ||||||
|  |   transform: { | ||||||
|  |     "^.+\\.(js|jsx|ts|tsx)$": ["babel-jest", { presets: ["next/babel"] }], | ||||||
|  |   }, | ||||||
|  |   transformIgnorePatterns: ["/node_modules/", "^.+\\.module\\.(css|sass|scss)$"], | ||||||
|  |   testEnvironment: "jsdom", | ||||||
|  |   moduleNameMapper: { | ||||||
|  |     "^@components(.*)$": "<rootDir>/components$1", | ||||||
|  |     "^@lib(.*)$": "<rootDir>/lib$1", | ||||||
|  |   }, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | export default config; | ||||||
							
								
								
									
										25
									
								
								jest.playwright.config.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								jest.playwright.config.js
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,25 @@ | ||||||
|  | module.exports = { | ||||||
|  |   verbose: true, | ||||||
|  |   preset: "jest-playwright-preset", | ||||||
|  |   transform: { | ||||||
|  |     "^.+\\.ts$": "ts-jest", | ||||||
|  |   }, | ||||||
|  |   testMatch: ["<rootDir>/playwright/**/?(*.)+(spec|test).[jt]s?(x)"], | ||||||
|  |   testEnvironmentOptions: { | ||||||
|  |     "jest-playwright": { | ||||||
|  |       browsers: ["chromium" /*, 'firefox', 'webkit'*/], | ||||||
|  |       exitOnPageError: false, | ||||||
|  |       launchOptions: { | ||||||
|  |         // launch headless on CI, in browser locally
 | ||||||
|  |         headless: !!process.env.CI, | ||||||
|  |         executablePath: process.env.PLAYWRIGHT_CHROME_EXECUTABLE_PATH, | ||||||
|  |       }, | ||||||
|  |       contextOptions: { | ||||||
|  |         recordVideo: { | ||||||
|  |           dir: "playwright/videos/", | ||||||
|  |         }, | ||||||
|  |       }, | ||||||
|  |       collectCoverage: true, | ||||||
|  |     }, | ||||||
|  |   }, | ||||||
|  | }; | ||||||
							
								
								
									
										29
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										29
									
								
								package.json
									
									
									
									
									
								
							|  | @ -12,7 +12,8 @@ | ||||||
|     "db-seed": "yarn ts-node scripts/seed.ts", |     "db-seed": "yarn ts-node scripts/seed.ts", | ||||||
|     "db-nuke": "docker compose down --volumes --remove-orphans", |     "db-nuke": "docker compose down --volumes --remove-orphans", | ||||||
|     "dx": "cross-env BASE_URL=http://localhost:3000 JWT_SECRET=secret DATABASE_URL=postgresql://postgres:@localhost:5450/calendso run-s db-up db-migrate db-seed dev", |     "dx": "cross-env BASE_URL=http://localhost:3000 JWT_SECRET=secret DATABASE_URL=postgresql://postgres:@localhost:5450/calendso run-s db-up db-migrate db-seed dev", | ||||||
|     "test": "node node_modules/.bin/jest", |     "test": "jest", | ||||||
|  |     "test-playwright": "jest --maxWorkers=2 --config jest.playwright.config.js && nyc report --reporter=lcov", | ||||||
|     "build": "next build", |     "build": "next build", | ||||||
|     "start": "next start", |     "start": "next start", | ||||||
|     "ts-node": "ts-node --compiler-options \"{\\\"module\\\":\\\"commonjs\\\"}\"", |     "ts-node": "ts-node --compiler-options \"{\\\"module\\\":\\\"commonjs\\\"}\"", | ||||||
|  | @ -108,6 +109,9 @@ | ||||||
|     "@typescript-eslint/eslint-plugin": "^4.30.0", |     "@typescript-eslint/eslint-plugin": "^4.30.0", | ||||||
|     "@typescript-eslint/parser": "^4.29.2", |     "@typescript-eslint/parser": "^4.29.2", | ||||||
|     "autoprefixer": "^10.3.1", |     "autoprefixer": "^10.3.1", | ||||||
|  |     "babel": "^6.23.0", | ||||||
|  |     "babel-jest": "^27.2.4", | ||||||
|  |     "babel-plugin-istanbul": "^6.0.0", | ||||||
|     "cross-env": "^7.0.3", |     "cross-env": "^7.0.3", | ||||||
|     "cypress": "^8.3.0", |     "cypress": "^8.3.0", | ||||||
|     "eslint": "^7.32.0", |     "eslint": "^7.32.0", | ||||||
|  | @ -117,13 +121,18 @@ | ||||||
|     "eslint-plugin-react-hooks": "^4.2.0", |     "eslint-plugin-react-hooks": "^4.2.0", | ||||||
|     "husky": "^7.0.1", |     "husky": "^7.0.1", | ||||||
|     "jest": "^27.2.2", |     "jest": "^27.2.2", | ||||||
|  |     "jest-playwright": "^0.0.1", | ||||||
|  |     "jest-playwright-preset": "^1.7.0", | ||||||
|     "lint-staged": "^11.1.2", |     "lint-staged": "^11.1.2", | ||||||
|     "mockdate": "^3.0.5", |     "mockdate": "^3.0.5", | ||||||
|     "npm-run-all": "^4.1.5", |     "npm-run-all": "^4.1.5", | ||||||
|  |     "nyc": "^15.1.0", | ||||||
|  |     "playwright": "^1.15.2", | ||||||
|     "postcss": "^8.3.6", |     "postcss": "^8.3.6", | ||||||
|     "prettier": "^2.3.2", |     "prettier": "^2.3.2", | ||||||
|     "prisma": "^2.30.2", |     "prisma": "^2.30.2", | ||||||
|     "tailwindcss": "^2.2.16", |     "tailwindcss": "^2.2.16", | ||||||
|  |     "ts-jest": "^27.0.5", | ||||||
|     "ts-node": "^10.2.1", |     "ts-node": "^10.2.1", | ||||||
|     "typescript": "^4.4.3" |     "typescript": "^4.4.3" | ||||||
|   }, |   }, | ||||||
|  | @ -132,23 +141,5 @@ | ||||||
|       "prettier --write", |       "prettier --write", | ||||||
|       "eslint" |       "eslint" | ||||||
|     ] |     ] | ||||||
|   }, |  | ||||||
|   "jest": { |  | ||||||
|     "verbose": true, |  | ||||||
|     "extensionsToTreatAsEsm": [ |  | ||||||
|       ".ts" |  | ||||||
|     ], |  | ||||||
|     "moduleFileExtensions": [ |  | ||||||
|       "js", |  | ||||||
|       "ts" |  | ||||||
|     ], |  | ||||||
|     "moduleNameMapper": { |  | ||||||
|       "^@components(.*)$": "<rootDir>/components$1", |  | ||||||
|       "^@lib(.*)$": "<rootDir>/lib$1" |  | ||||||
|     }, |  | ||||||
|     "testPathIgnorePatterns": [ |  | ||||||
|       "/node_modules/", |  | ||||||
|       "/cypress/" |  | ||||||
|     ] |  | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
							
								
								
									
										23
									
								
								playwright/initial.test.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								playwright/initial.test.ts
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,23 @@ | ||||||
|  | jest.setTimeout(35e3); | ||||||
|  | 
 | ||||||
|  | test("go to /pro", async () => { | ||||||
|  |   // Go to http://localhost:3000/auth/login
 | ||||||
|  |   await page.goto("http://localhost:3000/auth/login"); | ||||||
|  |   // Click input[name="email"]
 | ||||||
|  |   await page.click('input[name="email"]'); | ||||||
|  |   // Fill input[name="email"]
 | ||||||
|  |   await page.fill('input[name="email"]', "pro@example.com"); | ||||||
|  |   // Press Tab
 | ||||||
|  |   await page.press('input[name="email"]', "Tab"); | ||||||
|  |   // Fill input[name="password"]
 | ||||||
|  |   await page.fill('input[name="password"]', "pro"); | ||||||
|  |   // Press Enter
 | ||||||
|  |   await page.press('input[name="password"]', "Enter"); | ||||||
|  | 
 | ||||||
|  |   await page.waitForSelector("[data-testid=event-types]"); | ||||||
|  | 
 | ||||||
|  |   const $eventTypes = await page.$$("[data-testid=event-types] > *"); | ||||||
|  |   expect($eventTypes.length).toBeGreaterThanOrEqual(2); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | export {}; | ||||||
|  | @ -8,7 +8,6 @@ dayjs.extend(utc); | ||||||
| const EXPECTED_DATE_STRING = "2021-06-20T11:59:59+02:00"; | const EXPECTED_DATE_STRING = "2021-06-20T11:59:59+02:00"; | ||||||
| 
 | 
 | ||||||
| it("has the right utcOffset regardless of the local timeZone", async () => { | it("has the right utcOffset regardless of the local timeZone", async () => { | ||||||
|   expect(parseZone(EXPECTED_DATE_STRING).utcOffset()).toEqual(120); |   expect(parseZone(EXPECTED_DATE_STRING)?.utcOffset()).toEqual(120); | ||||||
|   expect(parseZone(EXPECTED_DATE_STRING).format()).toEqual(EXPECTED_DATE_STRING); |   expect(parseZone(EXPECTED_DATE_STRING)?.format()).toEqual(EXPECTED_DATE_STRING); | ||||||
|   expect(dayjs(EXPECTED_DATE_STRING).format()).not.toEqual(EXPECTED_DATE_STRING); |  | ||||||
| }); | }); | ||||||
|  |  | ||||||
|  | @ -20,7 +20,8 @@ | ||||||
|     "moduleResolution": "node", |     "moduleResolution": "node", | ||||||
|     "resolveJsonModule": true, |     "resolveJsonModule": true, | ||||||
|     "isolatedModules": true, |     "isolatedModules": true, | ||||||
|     "jsx": "preserve" |     "jsx": "preserve", | ||||||
|  |     "types": ["@types/jest", "jest-playwright-preset", "expect-playwright"] | ||||||
|   }, |   }, | ||||||
|   "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", "lib/*.js"], |   "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", "lib/*.js"], | ||||||
|   "exclude": ["node_modules"] |   "exclude": ["node_modules"] | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Alex Johansson
						Alex Johansson