From 0188cd4fec23817c3e979d5dce452d930f431100 Mon Sep 17 00:00:00 2001 From: Nina Perone Date: Tue, 16 Apr 2024 16:26:31 -0400 Subject: [PATCH] added testing --- .github/workflows/playwright.yml | 27 ++++++++++ .gitignore | 7 ++- package-lock.json | 91 ++++++++++++++++++++++++++++++++ package.json | 14 +++++ playwright.config.js | 79 +++++++++++++++++++++++++++ tests/app.spec.js | 73 +++++++++++++++++++++++++ 6 files changed, 290 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/playwright.yml create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 playwright.config.js create mode 100644 tests/app.spec.js diff --git a/.github/workflows/playwright.yml b/.github/workflows/playwright.yml new file mode 100644 index 0000000..467190b --- /dev/null +++ b/.github/workflows/playwright.yml @@ -0,0 +1,27 @@ +name: Playwright Tests +on: + push: + branches: [ main, master ] + pull_request: + branches: [ main, master ] +jobs: + test: + timeout-minutes: 60 + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: lts/* + - 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@v4 + if: always() + with: + name: playwright-report + path: playwright-report/ + retention-days: 30 diff --git a/.gitignore b/.gitignore index 24d9924..c102731 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,6 @@ -/receiptifyv1/config.js \ No newline at end of file +/receiptifyv1/config.js +node_modules/ +/test-results/ +/playwright-report/ +/blob-report/ +/playwright/.cache/ diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..d49d866 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,91 @@ +{ + "name": "receiptify-split-the-bill", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "receiptify-split-the-bill", + "version": "1.0.0", + "license": "ISC", + "devDependencies": { + "@playwright/test": "^1.43.1", + "@types/node": "^20.12.7" + } + }, + "node_modules/@playwright/test": { + "version": "1.43.1", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.43.1.tgz", + "integrity": "sha512-HgtQzFgNEEo4TE22K/X7sYTYNqEMMTZmFS8kTq6m8hXj+m1D8TgwgIbumHddJa9h4yl4GkKb8/bgAl2+g7eDgA==", + "dev": true, + "dependencies": { + "playwright": "1.43.1" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/@types/node": { + "version": "20.12.7", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.7.tgz", + "integrity": "sha512-wq0cICSkRLVaf3UGLMGItu/PtdY7oaXaI/RVU+xliKVOtRna3PRY57ZDfztpDL0n11vfymMUnXv8QwYCO7L1wg==", + "dev": true, + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "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/playwright": { + "version": "1.43.1", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.43.1.tgz", + "integrity": "sha512-V7SoH0ai2kNt1Md9E3Gwas5B9m8KR2GVvwZnAI6Pg0m3sh7UvgiYhRrhsziCmqMJNouPckiOhk8T+9bSAK0VIA==", + "dev": true, + "dependencies": { + "playwright-core": "1.43.1" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=16" + }, + "optionalDependencies": { + "fsevents": "2.3.2" + } + }, + "node_modules/playwright-core": { + "version": "1.43.1", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.43.1.tgz", + "integrity": "sha512-EI36Mto2Vrx6VF7rm708qSnesVQKbxEWvPrfA1IPY6HgczBplDx7ENtx+K2n4kJ41sLLkuGfmb0ZLSSXlDhqPg==", + "dev": true, + "bin": { + "playwright-core": "cli.js" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..5209f0f --- /dev/null +++ b/package.json @@ -0,0 +1,14 @@ +{ + "name": "receiptify-split-the-bill", + "version": "1.0.0", + "description": "Receiptify: Split the Bill is inspired by the original Receiptify, a web application that generates receipts that lists out a user's top tracks in the past, month, 6 months, and all time. Our version of receiptify generates receipts based on a group of users in a session. Our application generates a combined music receipt that displays a compiled list of all users' top tracks in the past, month, 6 months, and all time.", + "main": "index.js", + "scripts": {}, + "keywords": [], + "author": "", + "license": "ISC", + "devDependencies": { + "@playwright/test": "^1.43.1", + "@types/node": "^20.12.7" + } +} diff --git a/playwright.config.js b/playwright.config.js new file mode 100644 index 0000000..b15af2e --- /dev/null +++ b/playwright.config.js @@ -0,0 +1,79 @@ +// @ts-check +const { defineConfig, devices } = require('@playwright/test'); + +/** + * Read environment variables from file. + * https://github.com/motdotla/dotenv + */ +// require('dotenv').config(); + +/** + * @see https://playwright.dev/docs/test-configuration + */ +module.exports = 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 start', + // url: 'http://127.0.0.1:3000', + // reuseExistingServer: !process.env.CI, + // }, +}); + diff --git a/tests/app.spec.js b/tests/app.spec.js new file mode 100644 index 0000000..6d72b2a --- /dev/null +++ b/tests/app.spec.js @@ -0,0 +1,73 @@ +// @ts-check +const { test, expect } = require("@playwright/test"); +//const { test, expect } = require("playwright-test-coverage"); + + +test('homepage has title', async ({ page }) => { + await page.goto('http://localhost:3000/'); + + // Expect a title "to contain" a substring. + await expect(page).toHaveTitle(/Receiptify/); +}); + +test('join has title', async ({ page }) => { + await page.goto('http://localhost:3000/join'); + + // Expect a title "to contain" a substring. + await expect(page).toHaveTitle(/Join/); +}); + +test('verify login link', async ({ page }) => { + await page.goto('http://localhost:3000/'); + + // Wait for the link element to appear on the page + const link = await page.waitForSelector('a[href="/login"]'); + + // Check if the link exists + expect(link).not.toBeNull(); +}); + +test('verify join link', async ({ page }) => { + await page.goto('http://localhost:3000/'); + + // Wait for the link element to appear on the page + const link = await page.waitForSelector('a[href="/join"]'); + + // Check if the link exists + expect(link).not.toBeNull(); +}); + +test('verify receipt shown with sessionID', async ({ page }) => { + await page.goto('http://localhost:3000/#client=spotify&access_token=BQAzDrIGbK7zymnqRlL4lvoUAikbeTo5XmSYs8ZWO3PlQaqHOEvVMwfHB8-Y0tAljDFjkkV-ZOdRJmUl7bFnP542pQsQVUPvFF8sSjhAc8T8ULSOyTc2q7NcUyzXL4Jo1Aoa3_J4dn_QNHRkrPM2sqV0xKIL55iTGV5EHl90Owic5f1aZWN8VmD6JBDDoZbgLhpel4bkJCpWlEQWORQTj_tfaizdyOk6LGcKB0V0Fa8om8e39bUzCeGS&refresh_token=AQCj4b-7yq4VNNQpZq5eGCjsyEIEnPxWufw-8cJ6rsf2bKn4oiUDbV_f2Hvy86B7nJWYSVN0IDJ0MWBp4SuxKKsqka89FS2cugj4c2yTz1QfYiQs0BTpCFFLhNaoeV6qy-4&sessionID=660497'); + + // Wait for an element containing the word to appear on the page + await page.waitForSelector('body'); // Wait for the body element to ensure the page is loaded + const textContent = await page.textContent('body'); + + // Check if the word is present in the page content + //const word = 'SESSIONID'; + const word = 'SESSIONID'; + // @ts-ignore + const isWordPresent = textContent.toLowerCase().includes(word.toLowerCase()); + + // Assert that the word is present + expect(isWordPresent).toBe(true); + +}); + +test('verify receipt shown with display name', async ({ page }) => { + await page.goto('http://localhost:3000/#client=spotify&access_token=BQAzDrIGbK7zymnqRlL4lvoUAikbeTo5XmSYs8ZWO3PlQaqHOEvVMwfHB8-Y0tAljDFjkkV-ZOdRJmUl7bFnP542pQsQVUPvFF8sSjhAc8T8ULSOyTc2q7NcUyzXL4Jo1Aoa3_J4dn_QNHRkrPM2sqV0xKIL55iTGV5EHl90Owic5f1aZWN8VmD6JBDDoZbgLhpel4bkJCpWlEQWORQTj_tfaizdyOk6LGcKB0V0Fa8om8e39bUzCeGS&refresh_token=AQCj4b-7yq4VNNQpZq5eGCjsyEIEnPxWufw-8cJ6rsf2bKn4oiUDbV_f2Hvy86B7nJWYSVN0IDJ0MWBp4SuxKKsqka89FS2cugj4c2yTz1QfYiQs0BTpCFFLhNaoeV6qy-4&sessionID=660497'); + + // Wait for an element containing the word to appear on the page + await page.waitForSelector('body'); // Wait for the body element to ensure the page is loaded + const textContent = await page.textContent('body'); + + // Check if the word is present in the page content + const word = 'Nina Perone'; + // @ts-ignore + const isWordPresent = textContent.toLowerCase().includes(word.toLowerCase()); + + // Assert that the word is present + expect(isWordPresent).toBe(true); + +}); \ No newline at end of file