diff --git a/.github/wip-playwright.yml b/.github/wip-playwright.yml new file mode 100644 index 0000000000..29c87ca950 --- /dev/null +++ b/.github/wip-playwright.yml @@ -0,0 +1,28 @@ +name: Playwright Tests +on: + push: + branches: [ main, master ] + pull_request: + branches: [ main, master ] +jobs: + tests_e2e: + name: Run end-to-end tests + timeout-minutes: 60 + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: 18 + - name: Install dependencies + run: npm ci + - name: Install Playwright Browsers + run: npx playwright install --with-deps + - name: Run Playwright tests + run: npx playwright test + - uses: actions/upload-artifact@v3 + if: always() + with: + name: playwright-report + path: e2e/playwright-report/ + retention-days: 30 diff --git a/.gitignore b/.gitignore index 8f3751fd13..c7db0d1e8f 100644 --- a/.gitignore +++ b/.gitignore @@ -46,11 +46,14 @@ bower_components/ .flooignore # Environment +.npmrc .env cache.json api/data/ owner.yml archive .vscode/settings.json - -src/style - official.css \ No newline at end of file +src/style - official.css +/e2e/specs/.test-results/ +/e2e/playwright-report/ +/playwright/.cache/ diff --git a/api/app/clients/chatgpt-browser.js b/api/app/clients/chatgpt-browser.js index 0ba78b7c78..e3b28118b4 100644 --- a/api/app/clients/chatgpt-browser.js +++ b/api/app/clients/chatgpt-browser.js @@ -22,7 +22,7 @@ const browserClient = async ({ const clientOptions = { // Warning: This will expose your access token to a third party. Consider the risks before using this. - reverseProxyUrl: 'https://bypass.duti.tech/api/conversation', + reverseProxyUrl: 'https://bypass.churchless.tech/api/conversation', // Access token from https://chat.openai.com/api/auth/session accessToken: process.env.CHATGPT_TOKEN, model: modelMap.get(model), diff --git a/e2e/playwright.config.js b/e2e/playwright.config.js new file mode 100644 index 0000000000..86bb298c04 --- /dev/null +++ b/e2e/playwright.config.js @@ -0,0 +1,79 @@ +import { defineConfig, devices } from '@playwright/test'; +import path from 'path'; + +export default defineConfig({ + testDir: 'specs/', + outputDir: 'specs/.test-results', + /* Run tests in files in parallel. + NOTE: This sometimes causes issues on Windows. + Set to false if you experience issues running on a Windows machine. */ + fullyParallel: true, + /* Fail the build on CI if you accidentally left test.only in the source code. */ + forbidOnly: !!process.env.CI, + /* Retry on CI only */ + retries: process.env.CI ? 2 : 0, + /* Opt out of parallel tests on CI. */ + workers: process.env.CI ? 1 : undefined, + /* Reporter to use. See https://playwright.dev/docs/test-reporters */ + reporter: [ + ['html', { outputFolder: 'playwright-report' }] + ], + /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */ + use: { + baseURL: 'http:/localhost:3080', + video: 'on-first-retry', + trace: 'retain-on-failure', + headless: true, + storageState: path.resolve('./e2e/storageState.json'), + screenshot: 'only-on-failure', + }, + expect: { + timeout: 10000, + }, + /* Configure projects for major browsers */ + projects: [ + { + name: 'chromium', + use: { ...devices['Desktop Chrome'] }, + }, + + // Note: enabling these will slow down the CI and is probably unnecessary. + // { + // name: 'firefox', + // use: { ...devices['Desktop Firefox'] }, + // }, + + // { + // name: 'webkit', + // use: { ...devices['Desktop Safari'] }, + // }, + + /* Test against mobile viewports. */ + // { + // name: 'Mobile Chrome', + // use: { ...devices['Pixel 5'] }, + // }, + // { + // name: 'Mobile Safari', + // use: { ...devices['iPhone 12'] }, + // }, + + /* Test against branded browsers. */ + // { + // name: 'Microsoft Edge', + // use: { ...devices['Desktop Edge'], channel: 'msedge' }, + // }, + // { + // name: 'Google Chrome', + // use: { ..devices['Desktop Chrome'], channel: 'chrome' }, + // }, + ], + + /* Run your local dev server before starting the tests */ + webServer: { + command: 'node ../api/server/index.js', + url: 'http://localhost:3080', + timeout: 30_000, + reuseExistingServer: !process.env.CI, + }, +}); diff --git a/e2e/specs/landing.spec.js b/e2e/specs/landing.spec.js new file mode 100644 index 0000000000..9582cd0a4c --- /dev/null +++ b/e2e/specs/landing.spec.js @@ -0,0 +1,7 @@ +import {expect, test} from '@playwright/test'; + +test('landing page', async ({page}) => { + await page.goto('/'); + expect (await page.title()).toBe('ChatGPT Clone'); + expect (await page.textContent('h1')).toBe('ChatGPT Clone'); +}); \ No newline at end of file diff --git a/e2e/storageState.json b/e2e/storageState.json new file mode 100644 index 0000000000..9e26dfeeb6 --- /dev/null +++ b/e2e/storageState.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000000..8104979c58 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,170 @@ +{ + "name": "chatgpt-clone", + "version": "0.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "chatgpt-clone", + "version": "0.1.0", + "license": "ISC", + "devDependencies": { + "@playwright/test": "^1.32.1", + "cross-env": "^7.0.3", + "playwright": "^1.32.1" + } + }, + "node_modules/@playwright/test": { + "version": "1.32.1", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.32.1.tgz", + "integrity": "sha512-FTwjCuhlm1qHUGf4hWjfr64UMJD/z0hXYbk+O387Ioe6WdyZQ+0TBDAc6P+pHjx2xCv1VYNgrKbYrNixFWy4Dg==", + "dev": true, + "dependencies": { + "@types/node": "*", + "playwright-core": "1.32.1" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=14" + }, + "optionalDependencies": { + "fsevents": "2.3.2" + } + }, + "node_modules/@types/node": { + "version": "18.15.10", + "resolved": "https://registry.npmjs.org/@types/node/-/@types/node-18.15.10.tgz", + "integrity": "sha1-TuIXHDMGoYXRII2tX0Ta497kz+M=", + "dev": true, + "license": "MIT" + }, + "node_modules/cross-env": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", + "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.1" + }, + "bin": { + "cross-env": "src/bin/cross-env.js", + "cross-env-shell": "src/bin/cross-env-shell.js" + }, + "engines": { + "node": ">=10.14", + "npm": ">=6", + "yarn": ">=1" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/playwright": { + "version": "1.32.1", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.32.1.tgz", + "integrity": "sha512-GnEizysWMvoqHC3I9l8+4/ZxeLwLNdJJG76xdKGxzOcIZDcw5RSk/FKrFb5CuA+zcLpjIM2p9eR9Z4CuUDkWXg==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "playwright-core": "1.32.1" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/playwright-core": { + "version": "1.32.1", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.32.1.tgz", + "integrity": "sha1-WhDDJAMyOwfXXqQo6+7YZqgLdqE=", + "dev": true, + "license": "Apache-2.0", + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000000..cd6ee993c4 --- /dev/null +++ b/package.json @@ -0,0 +1,25 @@ +{ + "name": "chatgpt-clone", + "version": "0.1.0", + "description": "", + "scripts": { + "e2e": "playwright test --config=e2e/playwright.config.js", + "e2e:update": "playwright test --config=e2e/playwright.config.js --update-snapshots", + "e2e:debug": "cross-env PWDEBUG=1 playwright test --config=e2e/playwright.config.js", + "e2e:report": "npx playwright show-report e2e/playwright-report" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/danny-avila/chatgpt-clone.git" + }, + "author": "", + "license": "ISC", + "bugs": { + "url": "https://github.com/danny-avila/chatgpt-clone/issues" + }, + "homepage": "https://github.com/danny-avila/chatgpt-clone#readme", + "devDependencies": { + "@playwright/test": "^1.32.1", + "cross-env": "^7.0.3" + } +}