From 7cf68ea1f3c32de18d8a28c2245fcb3f56d6d2d1 Mon Sep 17 00:00:00 2001 From: Dimitar Nizamov Date: Thu, 1 Dec 2022 14:33:27 +0100 Subject: [PATCH] Playwright e2e Tests for the Donation Flow (#1110) * 1096 - setup playwright add tests for the first donation step * 1096 - add login page class and global setup * 1096 - add testing for full payment flow of a logged in user * 1096 - remove globalSetup.ts * 1096 - remove auth and change selectors on donation e2e tests * 1096 - add stripe webhook run script to the CI * start stripe webhook before playwright tests Signed-off-by: Ivan Milchev * remove yarn command for stripe webhook Signed-off-by: Ivan Milchev * start debugging session Signed-off-by: Ivan Milchev * record playwright tests Signed-off-by: Ivan Milchev * adjust stripe secrets Signed-off-by: Ivan Milchev * Admin can edit donations details imported from bank transfer (#1097) * added: admin can edit donor in donations grid * fixed: edit donor cell visible only when edit mode is on * added: update grid on edited person cell; add translations * fixed: edit cell only if provider is bank Co-authored-by: Margarita * Update Footer (#1092) * Migrate Footer styles * Update footer links * Remove unused translations from footer, fix footer links * Add title abobe footer link groups * Update footer links * Fix footer links translations * Fix translation typo * Style footer titles * Fix responsive styles for Footer * Remove Beta text from the logo (#1099) * Increase visible campaigns number (#1104) * Add SuperHosting partner in Footer (#1103) * Fix overlapping bug in Campaign Details page (#1106) * Add tag for successfull camapign (#1107) * update some gh actions Signed-off-by: Ivan Milchev * My profile tabs in mobile to be scrollable (#1114) * Consistent date format in update birthday modal (#1115) * Consistent date format in update birthday modal * Generic formatting of date in birthday modal * Enable Terms and Conditions and GDPR validation on Register form (#1126) * Enable Terms and Conditions and GDPR validation on Register form * Add terms and gdpr in RegisterFormData * [Improvement] Upgrade dependencies including Next 13 and React 18 (#1125) * 1123 - bump up next and react versions * 1123 - move out next middlewares * 1123 - migrate to new next/image api and add a11y todos * 1123 - fix layout='fill' images and migrate to new next/link api * 1123 - fix banner image on details page and LinkMenuItems * 1123 - update next-auth version and fix Link with the new next/link api * 1123 - fix next-auth type and cleanup conosole.log * 1123 - remove and replace console.logs from DonationTables * 1123 - add swcMinify to the config * 1123 - update i18n dependency * 1123 - fix fill image on the one time donation page * 1123 - update typescript, fix typings and add ExternalLinkMenuItem component * 1123 - fix @react-pdf typings and other left out * 1123 - revert test:e2e command * 1123 - remove unecessary resolution * 1123 - update support page e2e tests to match behaviour * 1123 - fix expects on the homepage tests and move out next/script * 1123 - update auth to now protect admin * add batebobo as a contributor for code (#1127) * update README.md [skip ci] * update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> * add valkirilov as a contributor for code, and doc (#1128) * update README.md [skip ci] * update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> * add devkishor8007 as a contributor for code (#1130) * update README.md [skip ci] * update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> * add stann1 as a contributor for code, doc, and 3 more (#1131) * update README.md [skip ci] * update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> * Typescript Downgrade and WhatsApp @mui/icons change (#1132) * 1123 - bump up next and react versions * 1123 - move out next middlewares * 1123 - migrate to new next/image api and add a11y todos * 1123 - fix layout='fill' images and migrate to new next/link api * 1123 - fix banner image on details page and LinkMenuItems * 1123 - update next-auth version and fix Link with the new next/link api * 1123 - fix next-auth type and cleanup conosole.log * 1123 - remove and replace console.logs from DonationTables * 1123 - add swcMinify to the config * 1123 - update i18n dependency * 1123 - fix fill image on the one time donation page * 1123 - update typescript, fix typings and add ExternalLinkMenuItem component * 1123 - fix @react-pdf typings and other left out * 1123 - revert test:e2e command * 1123 - remove unecessary resolution * 1123 - update support page e2e tests to match behaviour * 1123 - fix expects on the homepage tests and move out next/script * 1123 - update auth to now protect admin * change out WhatsAppOutlined for WhatsApp in `socialMedia.ts` * remove ts-expec-error from chat.tsx * return @ts-expect-error on the chat.tsx component * return typescript to 4.5.5 * update to typescript 4.8.3 * Fix visual issue with Menu items in the MainNav (#1121) * Fix visual issue with Menu items in the MainNav - increase the spacing between the Button and the opened dropdown with the Menu items so they don't interfere with the border of the "Donate" button in the MainNav References: #1016 * Refactoring of the GenericMenu component - chage the way we set the spacing between the `Button` and the `Menu` dropdown list to use `PaperProps` instead of wrapping it behind a `styled` component. It's simpler now. - rename the `GenericMenu` component to `GenericNavMenu` so it will distinguish its purpose way more clearly - fix the `id` attribute to be properly set via an input prop instead of using always the default wrong `menu-donation` for all items of this type * [Bug] You can click Next if you are both not logged and not anonymous (#1134) * 1133 - disable next button when not logged in * 1133 - fix anonymous submit value when mutating * 1133 - add option to be able to donate anonymous even if you are logged in * 1133 - remove console.logs * 1133 - add enum for auth step tabs * 1133 - change Tabs to strings * Modularize MUI imports and bump up MUI version (#1135) * Add expermental flag to modularize mui imports * Bump up mui versions and add modularizeImports experimental flag to the `next.config` * Fix Autocomplete import * 1109 (#1141) Added iban trimmed value on click copy button * 1113 Added border to button in login page (#1142) Removed unused variable, which causes warning * add AnzheloD as a contributor for code (#1143) * update README.md [skip ci] * update .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> * 1096 - setup playwright add tests for the first donation step * Remove env variables from the backend actoin * Revert yarn.lock to the origin/master file * 1096 - Update anonymous donation flow to match the new master changes * 1096 - return env secrets to the backend action * 1096 - change env variables down the list in the playwright.yml * 1096 - increase the timeout time for the wait on backend action * 1096 - change action api branch and add logging artifact * 1096 - remove unecessary api artifcat action values * 1096 - change api logs artifact path * Revert "1096 - change api logs artifact path" This reverts commit bba2bc7e7246eb657d180b4eef82958477e0b888. * 1096 - remove backend env variables from actions * store api and frontend logs to a file for playwright tests Signed-off-by: Ivan Milchev * set stripe secrets for api in playwright tests Signed-off-by: Ivan Milchev * another try of setting env for api in playwright Signed-off-by: Ivan Milchev * 1096 - remove the dependabot file * 1096 - remove change from LoginForm and add a comment to the logged in user test * try setting the env for playwright tests Signed-off-by: Ivan Milchev * added: setting version of yarn to ensure v3.3 will be called * Fix string litteral * set secrets explicitly for playwright workflow Signed-off-by: Ivan Milchev * set yarn version for playwright workflow in a separate step Signed-off-by: Ivan Milchev Signed-off-by: Ivan Milchev Co-authored-by: Ivan Milchev Co-authored-by: Margarita Co-authored-by: Margarita Co-authored-by: Ani Co-authored-by: Lachezar Marinov <99186919+marinovl7@users.noreply.github.com> Co-authored-by: Boyan Vushkov Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Valentin Kirilov Co-authored-by: Anzhelo Dimitrov <32179794+AnzheloD@users.noreply.github.com> Co-authored-by: quantum-grit Co-authored-by: Ilko Kacharov --- .github/workflows/check-pr.yml | 1 + .github/workflows/playwright.yml | 35 +++++++++++-- e2e/AuthPage.ts | 31 +++++++++++ e2e/local/donation.spec.ts | 88 ++++++++++++++++++++++++++++++++ playwright.config.ts | 2 +- 5 files changed, 152 insertions(+), 5 deletions(-) create mode 100644 e2e/AuthPage.ts create mode 100644 e2e/local/donation.spec.ts diff --git a/.github/workflows/check-pr.yml b/.github/workflows/check-pr.yml index f7e06bd39..b7611035c 100644 --- a/.github/workflows/check-pr.yml +++ b/.github/workflows/check-pr.yml @@ -89,3 +89,4 @@ jobs: run-playwright: name: Run Playwright uses: ./.github/workflows/playwright.yml + secrets: inherit diff --git a/.github/workflows/playwright.yml b/.github/workflows/playwright.yml index a0018936d..7ebf3f398 100644 --- a/.github/workflows/playwright.yml +++ b/.github/workflows/playwright.yml @@ -19,6 +19,9 @@ jobs: ref: master path: './api' + - name: Set yarn version + run: yarn set version berry + - name: Get yarn cache directory path id: yarn-cache-dir-path run: echo "dir=$(yarn config get cacheFolder)" >> $GITHUB_OUTPUT @@ -35,17 +38,32 @@ jobs: - name: Run db working-directory: ./api run: docker compose up -d pg-db + + - name: Run stripe webhook + working-directory: ./api + env: + STRIPE_WEBHOOK_SECRET: ${{ secrets.STRIPE_WEBHOOK_SECRET }} + STRIPE_SECRET_KEY: ${{ secrets.STRIPE_SECRET_KEY }} + run: docker compose up -d stripe-webhook + - uses: actions/setup-node@v3 with: node-version: '18' - - name: Install backend dependencies and seed database + - name: Install backend dependencies + working-directory: ./api + run: yarn + + - name: Seed database working-directory: ./api - run: yarn && yarn prisma generate && yarn prisma migrate deploy && yarn prisma db seed + run: yarn prisma generate && yarn prisma migrate deploy && yarn prisma db seed - name: Run backend working-directory: ./api - run: yarn start & + env: + STRIPE_WEBHOOK_SECRET: ${{ secrets.STRIPE_WEBHOOK_SECRET }} + STRIPE_SECRET_KEY: ${{ secrets.STRIPE_SECRET_KEY }} + run: yarn start &> api.log & - name: Install Frontend Dependencies working-directory: ./frontend @@ -71,7 +89,7 @@ jobs: - name: Start frontend working-directory: ./frontend - run: yarn start & + run: yarn start &> frontend.log & - name: Install Playwright Browsers working-directory: ./frontend @@ -93,3 +111,12 @@ jobs: name: playwright-report path: ./frontend/playwright-report/ retention-days: 14 + + - uses: actions/upload-artifact@v3 + if: failure() + with: + name: logs + path: | + ./frontend/frontend.log + ./api/api.log + retention-days: 14 diff --git a/e2e/AuthPage.ts b/e2e/AuthPage.ts new file mode 100644 index 000000000..5bbee26a3 --- /dev/null +++ b/e2e/AuthPage.ts @@ -0,0 +1,31 @@ +import { Page } from '@playwright/test' + +const credentials = { + username: process.env.USERNAME ?? 'admin@podkrepi.bg', + password: process.env.PASSWORD ?? '$ecurePa33', +} + +export class AuthPage { + page: Page + constructor(page: Page) { + this.page = page + } + + async _submitLoginForm() { + await this.page.click('input[type="email"]') + await this.page.fill('input[type="email"]', credentials.username) + await this.page.click('input[type="password"]') + await this.page.fill('input[type="password"]', credentials.password) + await this.page.click('text="Вход"') + await this.page.waitForNavigation({ waitUntil: 'networkidle' }) + } + + async login() { + await Promise.all([ + this.page.goto('http://localhost:3040/login'), + this.page.waitForNavigation(), + ]) + + await this._submitLoginForm() + } +} diff --git a/e2e/local/donation.spec.ts b/e2e/local/donation.spec.ts new file mode 100644 index 000000000..aea2602c3 --- /dev/null +++ b/e2e/local/donation.spec.ts @@ -0,0 +1,88 @@ +import { test, expect } from '@playwright/test' + +test.beforeEach(async ({ page }) => { + await page.goto('http://localhost:3040/', { waitUntil: 'networkidle' }) + await page.locator('text="Подкрепете сега"').first().click() + await page.waitForURL((url) => url.pathname.includes('/campaigns/donation')) +}) + +test.describe('donation page init', () => { + test('test rendering and defaults', async ({ page }) => { + await expect( + page.locator('label', { has: page.locator('text=Карта') }).locator('input[type="radio"]'), + ).toBeChecked() + await expect( + page + .locator('label', { has: page.locator('text=Банков превод') }) + .locator('input[type="radio"]'), + ).not.toBeChecked() + }) +}) + +//This test will not pass since the keycloak is not yet working in the e2e tests + +// test.describe('logged in user donation flow', () => { +// test('choosing a predefined value and donate', async ({ page }) => { +// // Choose a predefined value from the radio buttons +// await page.locator('input[value="card"]').check() +// await page.locator('input[value="500"]').check() + +// // Click checkbox to cover the tax by stripe +// await page.locator('input[name="cardIncludeFees"]').check() +// await page.locator('button:has-text("Напред")').click() + +// await expect(page.locator('text=Вече сте влезли във Вашия профил')).toBeDefined() +// await page.locator('button:has-text("Напред")').click() + +// await page.fill('textarea', 'Test message') +// await page.locator('button:has-text("Премини към плащане")').click() + +// await page.waitForURL((url) => url.host === 'checkout.stripe.com') + +// await expect(page.locator('text=BGN 5.00')).toBeDefined() +// await page.locator('input[name="email"]').fill('admin@podkrepi.bg') +// await page.locator('input[name="cardNumber"]').fill('4242424242424242') +// await page.locator('input[name="cardExpiry"]').fill('0424') +// await page.locator('input[name="cardCvc"]').fill('123') +// await page.locator('input[name="billingName"]').fill('John Doe') +// await page.locator('select[name="billingCountry"]').selectOption('BG') + +// await page.locator('button[data-testid="hosted-payment-submit-button"]').click() + +// await page.waitForURL((url) => url.searchParams.get('success') === 'true') + +// await expect(page.locator('text=Благодарим за доверието и подкрепата!')).toBeDefined() +// }) +// }) + +test.describe('anonymous user donation flow', () => { + test('choosing a custom value and continuing', async ({ page }) => { + // Choose a predefined value from the radio buttons + await page.locator('input[value="card"]').check() + await page.locator('input[value="500"]').check() + + // Click checkbox to cover the tax by stripe + await page.locator('input[name="cardIncludeFees"]').check() + await page.locator('button:has-text("Напред")').click() + + page.locator('text=Дарете анонимно').click() + await page.locator('button:has-text("Напред")').click() + + await page.fill('textarea', 'е2е_tester') + await page.locator('button:has-text("Премини към плащане")').click() + + await expect(page.locator('text=BGN 5.00')).toBeDefined() + await page.locator('input[name="email"]').fill('anon_e2e_tester@podkrepi.bg') + await page.locator('input[name="cardNumber"]').fill('4242424242424242') + await page.locator('input[name="cardExpiry"]').fill('0424') + await page.locator('input[name="cardCvc"]').fill('123') + await page.locator('input[name="billingName"]').fill('John Doe') + await page.locator('select[name="billingCountry"]').selectOption('BG') + + await page.locator('button[data-testid="hosted-payment-submit-button"]').click() + + await page.waitForURL((url) => url.searchParams.get('success') === 'true') + + await expect(page.locator('text=Благодарим за доверието и подкрепата!')).toBeDefined() + }) +}) diff --git a/playwright.config.ts b/playwright.config.ts index 7f7362acd..ac58ae038 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -36,7 +36,7 @@ const config: PlaywrightTestConfig = { /* Maximum time each action such as `click()` can take. Defaults to 0 (no limit). */ actionTimeout: 0, /* Base URL to use in actions like `await page.goto('/')`. */ - // baseURL: 'http://localhost:3000', + baseURL: process.env.BASE_URL || 'http://localhost:3040', /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */ trace: 'on-first-retry',