From 6eafe0d2a8070ee6b5550a685922df8b74f6564f Mon Sep 17 00:00:00 2001 From: "sp.wack" <83104063+amanape@users.noreply.github.com> Date: Tue, 5 Nov 2024 17:12:58 +0200 Subject: [PATCH] feat(frontend): Redirect user to app after a project upload or repo selection (and add e2e tests) (#4751) --- frontend/.gitignore | 5 ++ frontend/package-lock.json | 60 ++++++++++++++ frontend/package.json | 2 + frontend/playwright.config.ts | 79 +++++++++++++++++++ .../src/components/buttons/ModalButton.tsx | 3 + .../modals/connect-to-github-modal.tsx | 1 + frontend/src/mocks/handlers.ts | 18 ++++- .../_oh._index/github-repo-selector.tsx | 10 ++- frontend/src/routes/_oh._index/route.tsx | 8 +- frontend/src/routes/_oh.tsx | 5 +- frontend/test-utils.tsx | 7 +- frontend/tests/fixtures/project.zip | 0 frontend/tests/redirect.spec.ts | 61 ++++++++++++++ frontend/vite.config.ts | 2 + 14 files changed, 253 insertions(+), 8 deletions(-) create mode 100644 frontend/playwright.config.ts create mode 100644 frontend/tests/fixtures/project.zip create mode 100644 frontend/tests/redirect.spec.ts diff --git a/frontend/.gitignore b/frontend/.gitignore index 471b78551b..d62bd04c1a 100644 --- a/frontend/.gitignore +++ b/frontend/.gitignore @@ -2,3 +2,8 @@ public/locales/**/* src/i18n/declaration.ts .env +node_modules/ +/test-results/ +/playwright-report/ +/blob-report/ +/playwright/.cache/ diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 79c71ed6da..fb34ca5286 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -46,6 +46,7 @@ "ws": "^8.18.0" }, "devDependencies": { + "@playwright/test": "^1.48.2", "@remix-run/dev": "^2.11.2", "@remix-run/testing": "^2.11.2", "@tailwindcss/typography": "^0.5.15", @@ -3379,6 +3380,21 @@ "url": "https://opencollective.com/unts" } }, + "node_modules/@playwright/test": { + "version": "1.48.2", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.48.2.tgz", + "integrity": "sha512-54w1xCWfXuax7dz4W2M9uw0gDyh+ti/0K/MxcCUxChFh37kkdxPdfZDw5QBbuPUJHr1CiHJ1hXgSs+GgeQc5Zw==", + "dev": true, + "dependencies": { + "playwright": "1.48.2" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/@polka/url": { "version": "1.0.0-next.28", "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.28.tgz", @@ -19422,6 +19438,50 @@ "pathe": "^1.1.2" } }, + "node_modules/playwright": { + "version": "1.48.2", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.48.2.tgz", + "integrity": "sha512-NjYvYgp4BPmiwfe31j4gHLa3J7bD2WiBz8Lk2RoSsmX38SVIARZ18VYjxLjAcDsAhA+F4iSEXTSGgjua0rrlgQ==", + "dev": true, + "dependencies": { + "playwright-core": "1.48.2" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "fsevents": "2.3.2" + } + }, + "node_modules/playwright-core": { + "version": "1.48.2", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.48.2.tgz", + "integrity": "sha512-sjjw+qrLFlriJo64du+EK0kJgZzoQPsabGF4lBvsid+3CNIZIYLgnMj9V6JY5VhM2Peh20DJWIVpVljLLnlawA==", + "dev": true, + "bin": { + "playwright-core": "cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/playwright/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/possible-typed-array-names": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", diff --git a/frontend/package.json b/frontend/package.json index faef772727..30c8895ee4 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -50,6 +50,7 @@ "build": "npm run make-i18n && tsc && remix vite:build", "start": "npx sirv-cli build/ --single", "test": "vitest run", + "test:e2e": "playwright test", "test:coverage": "npm run make-i18n && vitest run --coverage", "dev_wsl": "VITE_WATCH_USE_POLLING=true vite", "preview": "vite preview", @@ -71,6 +72,7 @@ ] }, "devDependencies": { + "@playwright/test": "^1.48.2", "@remix-run/dev": "^2.11.2", "@remix-run/testing": "^2.11.2", "@tailwindcss/typography": "^0.5.15", diff --git a/frontend/playwright.config.ts b/frontend/playwright.config.ts new file mode 100644 index 0000000000..53a4800443 --- /dev/null +++ b/frontend/playwright.config.ts @@ -0,0 +1,79 @@ +import { defineConfig, devices } from "@playwright/test"; + +/** + * Read environment variables from file. + * https://github.com/motdotla/dotenv + */ +// import dotenv from 'dotenv'; +// import path from 'path'; +// dotenv.config({ path: path.resolve(__dirname, '.env') }); + +/** + * See https://playwright.dev/docs/test-configuration. + */ +export default defineConfig({ + testDir: "./tests", + /* Run tests in files in parallel */ + 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", + /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */ + use: { + /* Base URL to use in actions like `await page.goto('/')`. */ + baseURL: "http://127.0.0.1:3000", + + /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */ + trace: "on-first-retry", + }, + + /* Configure projects for major browsers */ + projects: [ + { + name: "chromium", + use: { ...devices["Desktop Chrome"] }, + }, + + { + 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: "npm run dev:mock -- --port 3000", + url: "http://127.0.0.1:3000", + reuseExistingServer: !process.env.CI, + }, +}); diff --git a/frontend/src/components/buttons/ModalButton.tsx b/frontend/src/components/buttons/ModalButton.tsx index 29ec2ae5c5..e011fef760 100644 --- a/frontend/src/components/buttons/ModalButton.tsx +++ b/frontend/src/components/buttons/ModalButton.tsx @@ -2,6 +2,7 @@ import clsx from "clsx"; import React from "react"; interface ModalButtonProps { + testId?: string; variant?: "default" | "text-like"; onClick?: () => void; text: string; @@ -13,6 +14,7 @@ interface ModalButtonProps { } function ModalButton({ + testId, variant = "default", onClick, text, @@ -24,6 +26,7 @@ function ModalButton({ }: ModalButtonProps) { return (