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