diff --git a/packages/app/components/misc/ConnectWalletButton.tsx b/packages/app/components/misc/ConnectWalletButton.tsx index 39ac8aef6..668c546ba 100644 --- a/packages/app/components/misc/ConnectWalletButton.tsx +++ b/packages/app/components/misc/ConnectWalletButton.tsx @@ -16,7 +16,7 @@ export const ConnectWalletButton = ({ return ( ); diff --git a/packages/app/package.json b/packages/app/package.json index c848dd89b..ffd5b223b 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -101,9 +101,9 @@ "devDependencies": { "@dotenvx/dotenvx": "^1.0.1", "@playwright/test": "^1.37.0", - "@types/lodash": "^4.17.7", "@tailwindcss/typography": "^0.5.13", "@types/fuzzy-search": "^2.1.5", + "@types/lodash": "^4.17.7", "@types/node": "20.14.11", "@types/react": "18.2.37", "@types/react-color": "^3.0.11", diff --git a/packages/app/playwright.config.ts b/packages/app/playwright.config.ts index cebc91244..d6084023d 100644 --- a/packages/app/playwright.config.ts +++ b/packages/app/playwright.config.ts @@ -1,11 +1,7 @@ import { defineConfig, devices } from '@playwright/test' +import path from 'path'; -/** - * Read environment variables from file. - * https://github.com/motdotla/dotenv - */ -// import dotenv from 'dotenv'; -// dotenv.config({ path: path.resolve(__dirname, '.env') }); +require('dotenv').config({path: path.resolve(__dirname, 'test.env')}) /** * See https://playwright.dev/docs/test-configuration. @@ -13,13 +9,13 @@ import { defineConfig, devices } from '@playwright/test' export default defineConfig({ testDir: './tests', /* Run tests in files in parallel */ - fullyParallel: true, + fullyParallel: false, /* 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, + retries: process.env.CI ? 2 : 1, /* Opt out of parallel tests on CI. */ - workers: process.env.CI ? 1 : undefined, + workers: process.env.CI ? 1 : 2, /* 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. */ diff --git a/packages/app/tests/core.spec.ts b/packages/app/tests/core.spec.ts index 252dbe99c..4d637e908 100644 --- a/packages/app/tests/core.spec.ts +++ b/packages/app/tests/core.spec.ts @@ -1,7 +1,7 @@ import { test, expect } from '@playwright/test'; test('has title', async ({ page }) => { - await page.goto('http://localhost:3000/'); + await page.goto('http://localhost:3000/studio'); await expect(page).toHaveTitle(/StreamETH/); }); diff --git a/packages/app/tests/create.spec.ts b/packages/app/tests/create.spec.ts index 03015d8db..25ffdea01 100644 --- a/packages/app/tests/create.spec.ts +++ b/packages/app/tests/create.spec.ts @@ -1,11 +1,24 @@ -import { test, expect } from '@playwright/test'; +import { test as base, expect } from '@playwright/test'; import path from 'path'; import { IOrganization } from 'streameth-new-server/src/interfaces/organization.interface'; +import crypto from 'crypto'; + +const generateShortId = () => { + return crypto.randomBytes(3).toString('hex'); +}; + +const test = base.extend({ + orgId: async ({ browserName }, use, testInfo) => { + const baseEnv = process.env['ORG_NAME'] || 'TestOrg'; + const uniqueId = generateShortId(); + const orgId = `${baseEnv}_${browserName.toLowerCase()}_${uniqueId}`; + console.log(`Running test "${testInfo.title}" with ORG_ID: ${orgId}`); + await use(orgId); + }, +}); +const API_URL = process.env['NEXT_PUBLIC_API_URL'] || ''; -const ORG_NAME = 'test_organization'; -const API_URL = 'https://dev.api.streameth.org'; - -test.afterEach(async ({ request, context }) => { +test.afterEach(async ({ request, context, orgId }) => { try { // Step 1: Get the authentication token const cookies = await context.cookies(); @@ -35,7 +48,7 @@ test.afterEach(async ({ request, context }) => { const responseBody = await getResponse.json(); const organizations: IOrganization[] = responseBody.data; - const testOrg = organizations.find((org) => org.name === ORG_NAME); + const testOrg = organizations.find((org) => org.name === orgId); if (testOrg) { const organizationId = testOrg._id?.toString(); @@ -69,6 +82,7 @@ test.afterEach(async ({ request, context }) => { test('create an organization with all mandatory information', async ({ page, + orgId, }) => { // Navigate to the create organization page await page.goto('http://localhost:3000/studio/create'); @@ -86,7 +100,7 @@ test('create an organization with all mandatory information', async ({ const name = page.getByPlaceholder('Name'); const email = page.getByPlaceholder('Email'); - await name.fill(ORG_NAME); + await name.fill(orgId); await page.waitForTimeout(200); await email.fill('test@example.com'); await page.waitForTimeout(200); @@ -111,6 +125,7 @@ test('create an organization with all mandatory information', async ({ test('create an organization with all mandatory information and description', async ({ page, + orgId, }) => { // Navigate to the create organization page await page.goto('http://localhost:3000/studio/create'); @@ -125,7 +140,7 @@ test('create an organization with all mandatory information and description', as await expect(heading).toBeVisible({ timeout: 20000 }); // Fill in the form - await page.getByPlaceholder('Name').fill(ORG_NAME); + await page.getByPlaceholder('Name').fill(orgId); await page.getByPlaceholder('Email').fill('test@example.com'); // Upload logo @@ -159,6 +174,7 @@ test('create an organization with all mandatory information and description', as test('create an organization with all mandatory information and a description too long', async ({ page, + orgId, }) => { // Navigate to the create organization page await page.goto('http://localhost:3000/studio/create'); @@ -173,7 +189,7 @@ test('create an organization with all mandatory information and a description to await expect(heading).toBeVisible({ timeout: 20000 }); // Fill in the form - await page.getByPlaceholder('Name').fill(ORG_NAME); + await page.getByPlaceholder('Name').fill(orgId); await page.getByPlaceholder('Email').fill('test@example.com'); // Upload logo @@ -223,6 +239,7 @@ test('create an organization with all mandatory information and a description to test('try to create an organization with missing the logo', async ({ page, + orgId, }) => { // Navigate to the create organization page await page.goto('http://localhost:3000/studio/create'); @@ -240,7 +257,7 @@ test('try to create an organization with missing the logo', async ({ const name = page.getByPlaceholder('Name'); const email = page.getByPlaceholder('Email'); - await name.fill(ORG_NAME); + await name.fill(orgId); await page.waitForTimeout(200); await email.fill('test@example.com'); await page.waitForTimeout(200); @@ -282,11 +299,12 @@ test('attempt to create an organization with missing name', async ({ test('attempt to create an organization with missing email', async ({ page, + orgId, }) => { await page.goto('http://localhost:3000/studio/create'); // Fill only name and upload logo - await page.getByPlaceholder('Name').fill(ORG_NAME); + await page.getByPlaceholder('Name').fill(orgId); const logoPath = path.join(__dirname, '..', 'public', 'logo.png'); const fileChooserPromise = page.waitForEvent('filechooser'); diff --git a/packages/app/tests/auth.setup.ts b/packages/app/tests/global.setup.ts similarity index 95% rename from packages/app/tests/auth.setup.ts rename to packages/app/tests/global.setup.ts index 2195fc18b..97e571642 100644 --- a/packages/app/tests/auth.setup.ts +++ b/packages/app/tests/global.setup.ts @@ -8,6 +8,7 @@ setup('login to studio page with Privy', async ({ page }) => { const otp = process.env['PRIVY_OTP'] || ''; // Find and click the login button + await page.getByRole('button', { name: 'Sign in' }).click(); const loginButton = page.getByRole('button', { name: 'Log in with email or socials', });