From e60a62db0eb51edafcc66c84c6ac6caf3a5908a9 Mon Sep 17 00:00:00 2001 From: Jeffrey Yu <35394596+JeffreytheCoder@users.noreply.github.com> Date: Sat, 13 Apr 2024 19:34:12 -0700 Subject: [PATCH 1/3] test: set up authentication --- packages/e2e-react/.gitignore | 3 +++ packages/e2e-react/README.md | 14 +++++++++++++ packages/e2e-react/package.json | 1 + packages/e2e-react/playwright.config.ts | 6 ++++-- packages/e2e-react/src/App.tsx | 2 -- packages/e2e-react/tests/auth.setup.ts | 21 +++++++++++++++++++ packages/e2e-react/tests/example.spec.ts | 16 +++++--------- packages/e2e-react/tests/helpers.ts | 9 ++++++++ .../src/components/ChatInput/ChatInput.js | 6 +++++- packages/react/src/components/EmbeddedChat.js | 1 + .../react/src/components/auth/LoginForm.js | 3 +++ yarn.lock | 8 +++++++ 12 files changed, 74 insertions(+), 16 deletions(-) create mode 100644 packages/e2e-react/tests/auth.setup.ts create mode 100644 packages/e2e-react/tests/helpers.ts diff --git a/packages/e2e-react/.gitignore b/packages/e2e-react/.gitignore index b88c8135ab..1a6b5a32a1 100644 --- a/packages/e2e-react/.gitignore +++ b/packages/e2e-react/.gitignore @@ -26,3 +26,6 @@ dist-ssr /playwright-report/ /blob-report/ /playwright/.cache/ + +.env +.auth diff --git a/packages/e2e-react/README.md b/packages/e2e-react/README.md index 181d94ad92..688ce4a05d 100644 --- a/packages/e2e-react/README.md +++ b/packages/e2e-react/README.md @@ -1 +1,15 @@ # E2E EmbeddedChat setup +1. Create an `.env` with your Rocket.Chat username and password +``` +USERNAME=[your_username] +PASSWORD=[your_password] +``` +2. Make sure EmbeddedChat is running on `http://localhost:6006` +3. Run E2E tests +``` +yarn test +``` +Or run tests in interactive UI +``` +yarn test --ui +``` diff --git a/packages/e2e-react/package.json b/packages/e2e-react/package.json index 40a4543231..d19fa4fb19 100644 --- a/packages/e2e-react/package.json +++ b/packages/e2e-react/package.json @@ -25,6 +25,7 @@ "@typescript-eslint/eslint-plugin": "^6.21.0", "@typescript-eslint/parser": "^6.21.0", "@vitejs/plugin-react": "^4.2.1", + "dotenv": "^16.4.5", "eslint": "^8.56.0", "eslint-plugin-react-hooks": "^4.6.0", "eslint-plugin-react-refresh": "^0.4.5", diff --git a/packages/e2e-react/playwright.config.ts b/packages/e2e-react/playwright.config.ts index a91deee96a..ac470ca546 100644 --- a/packages/e2e-react/playwright.config.ts +++ b/packages/e2e-react/playwright.config.ts @@ -24,7 +24,7 @@ export default defineConfig({ /* 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:5173', + baseURL: 'http://localhost:6006', /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */ trace: 'on-first-retry', @@ -32,9 +32,11 @@ export default defineConfig({ /* Configure projects for major browsers */ projects: [ + { name: 'setup', testMatch: /.*\.setup\.ts/ }, { name: 'chromium', use: { ...devices['Desktop Chrome'] }, + dependencies: ['setup'], }, // { @@ -71,7 +73,7 @@ export default defineConfig({ /* Run your local dev server before starting the tests */ webServer: { command: 'yarn dev', - url: 'http://127.0.0.1:5173', + url: 'http://localhost:5173', reuseExistingServer: !process.env.CI, }, }); diff --git a/packages/e2e-react/src/App.tsx b/packages/e2e-react/src/App.tsx index 5be050dd0a..5236ed41d1 100644 --- a/packages/e2e-react/src/App.tsx +++ b/packages/e2e-react/src/App.tsx @@ -4,8 +4,6 @@ import { EmbeddedChat } from "@embeddedchat/react"; function App() { return ( ); diff --git a/packages/e2e-react/tests/auth.setup.ts b/packages/e2e-react/tests/auth.setup.ts new file mode 100644 index 0000000000..57cd5e3b4c --- /dev/null +++ b/packages/e2e-react/tests/auth.setup.ts @@ -0,0 +1,21 @@ +import { test as setup, expect } from '@playwright/test'; +import { getIframe } from './helpers'; +import dotenv from 'dotenv'; + +dotenv.config(); +const authFile = '.auth/user.json'; + +setup('authenticate', async ({ page }) => { + await page.goto('/'); + const iframe = await getIframe(page); + + await iframe.getByTestId('join-button').click(); + + await iframe.getByTestId('login-email').fill(process.env.USERNAME || ''); + await iframe.getByTestId('login-password').fill(process.env.PASSWORD || ''); + + await iframe.getByTestId('login-button').click(); + await expect(iframe.getByTestId('join-button')).toBeHidden(); + + await page.context().storageState({ path: authFile }); +}); diff --git a/packages/e2e-react/tests/example.spec.ts b/packages/e2e-react/tests/example.spec.ts index 4e9ba05899..19dfdc1b2b 100644 --- a/packages/e2e-react/tests/example.spec.ts +++ b/packages/e2e-react/tests/example.spec.ts @@ -1,18 +1,12 @@ import { test, expect } from '@playwright/test'; +import { getIframe } from './helpers'; -test('EmbeddedChat should render', async ({ page }) => { - await page.goto('/'); - await expect(page.locator('.ec-embedded-chat')).toBeVisible(); -}); - -test('EmbeddedChat has a title', async ({ page }) => { +test.beforeEach('open page', async ({ page }) => { await page.goto('/'); - await expect(page.locator('.ec-chat-header--channelDescription')).toHaveText('Login to chat'); }); -test('EmbeddedChat has messages', async ({ page }) => { - await page.goto('/'); +test('EmbeddedChat should render', async ({ page }) => { + const iframe = await getIframe(page); - await page.waitForSelector('.ec-message'); - expect(await page.locator('.ec-message').count()).toBeGreaterThan(0); + await expect(iframe.getByTestId('embedded-chat')).toBeVisible(); }); diff --git a/packages/e2e-react/tests/helpers.ts b/packages/e2e-react/tests/helpers.ts new file mode 100644 index 0000000000..0b83edbb87 --- /dev/null +++ b/packages/e2e-react/tests/helpers.ts @@ -0,0 +1,9 @@ +import { Page } from "@playwright/test"; + +export async function getIframe(page: Page) { + const iframe = page.frame({ name: 'storybook-preview-iframe' }); + if (!iframe) { + throw new Error('Could not find Storybook iframe'); + } + return iframe; +} diff --git a/packages/react/src/components/ChatInput/ChatInput.js b/packages/react/src/components/ChatInput/ChatInput.js index 18416d7927..ee707b23ab 100644 --- a/packages/react/src/components/ChatInput/ChatInput.js +++ b/packages/react/src/components/ChatInput/ChatInput.js @@ -575,7 +575,11 @@ const ChatInput = ({ scrollToBottom }) => { ) : ( - )} diff --git a/packages/react/src/components/EmbeddedChat.js b/packages/react/src/components/EmbeddedChat.js index 185932adde..e864676816 100644 --- a/packages/react/src/components/EmbeddedChat.js +++ b/packages/react/src/components/EmbeddedChat.js @@ -224,6 +224,7 @@ const EmbeddedChat = ({ onDragEnter={handleDragEnter} onDragLeave={handleDragLeave} onDrop={(e) => handleDragDrop(e)} + data-testid="embedded-chat" > {onDrag && } {hideHeader ? null : ( diff --git a/packages/react/src/components/auth/LoginForm.js b/packages/react/src/components/auth/LoginForm.js index bdfb854690..f392d357da 100644 --- a/packages/react/src/components/auth/LoginForm.js +++ b/packages/react/src/components/auth/LoginForm.js @@ -119,6 +119,7 @@ export default function LoginForm() { placeholder="example@example.com" onKeyPress={handleKeyPress} style={{ borderColor: usernameError ? 'red' : '' }} + data-testid="login-email" /> {usernameError && ( @@ -136,6 +137,7 @@ export default function LoginForm() { onChange={handleEditPassword} onKeyPress={handleKeyPress} style={{ borderColor: passwordError ? 'red' : '' }} + data-testid="login-password" /> Login diff --git a/yarn.lock b/yarn.lock index 5d3eeb7630..506366e19b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -14643,6 +14643,13 @@ __metadata: languageName: node linkType: hard +"dotenv@npm:^16.4.5": + version: 16.4.5 + resolution: "dotenv@npm:16.4.5" + checksum: 301a12c3d44fd49888b74eb9ccf9f07a1f5df43f489e7fcb89647a2edcd84c42d6bc349dc8df099cd18f07c35c7b04685c1a4f3e6a6a9e6b30f8d48c15b7f49c + languageName: node + linkType: hard + "dotenv@npm:^7.0.0": version: 7.0.0 resolution: "dotenv@npm:7.0.0" @@ -14702,6 +14709,7 @@ __metadata: "@typescript-eslint/eslint-plugin": ^6.21.0 "@typescript-eslint/parser": ^6.21.0 "@vitejs/plugin-react": ^4.2.1 + dotenv: ^16.4.5 eslint: ^8.56.0 eslint-plugin-react-hooks: ^4.6.0 eslint-plugin-react-refresh: ^0.4.5 From c9033ee39c1adb74cc207a46a071a5b5aaa69e82 Mon Sep 17 00:00:00 2001 From: Jeffrey Yu <35394596+JeffreytheCoder@users.noreply.github.com> Date: Sat, 13 Apr 2024 20:00:55 -0700 Subject: [PATCH 2/3] Remove annoymous mode --- packages/e2e-react/src/App.tsx | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/packages/e2e-react/src/App.tsx b/packages/e2e-react/src/App.tsx index 5236ed41d1..80f8e5f881 100644 --- a/packages/e2e-react/src/App.tsx +++ b/packages/e2e-react/src/App.tsx @@ -2,11 +2,7 @@ import { EmbeddedChat } from "@embeddedchat/react"; function App() { - return ( - - ); + return ; } export default App; From e46fd0a2d8e24ab3cb09c481631664a4710c96a3 Mon Sep 17 00:00:00 2001 From: Jeffrey Yu <35394596+JeffreytheCoder@users.noreply.github.com> Date: Sat, 13 Apr 2024 23:52:59 -0700 Subject: [PATCH 3/3] revert changes to enable CI tests --- packages/e2e-react/constants.ts | 3 +++ packages/e2e-react/playwright.config.ts | 4 ++-- packages/e2e-react/src/App.tsx | 8 +++++++- packages/e2e-react/tests/auth.setup.ts | 19 +++++++------------ packages/e2e-react/tests/example.spec.ts | 5 +---- packages/e2e-react/tests/helpers.ts | 9 --------- 6 files changed, 20 insertions(+), 28 deletions(-) create mode 100644 packages/e2e-react/constants.ts delete mode 100644 packages/e2e-react/tests/helpers.ts diff --git a/packages/e2e-react/constants.ts b/packages/e2e-react/constants.ts new file mode 100644 index 0000000000..654f796939 --- /dev/null +++ b/packages/e2e-react/constants.ts @@ -0,0 +1,3 @@ +export const TEST_USERNAME: string = 'tester'; +export const TEST_PASSWORD: string = 'tester'; +export const AUTH_FILE_PATH: string = '.auth/user.json'; diff --git a/packages/e2e-react/playwright.config.ts b/packages/e2e-react/playwright.config.ts index ac470ca546..248262f048 100644 --- a/packages/e2e-react/playwright.config.ts +++ b/packages/e2e-react/playwright.config.ts @@ -24,7 +24,7 @@ export default defineConfig({ /* 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://localhost:6006', + baseURL: 'http://127.0.0.1:5173', /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */ trace: 'on-first-retry', @@ -73,7 +73,7 @@ export default defineConfig({ /* Run your local dev server before starting the tests */ webServer: { command: 'yarn dev', - url: 'http://localhost:5173', + url: 'http://127.0.0.1:5173', reuseExistingServer: !process.env.CI, }, }); diff --git a/packages/e2e-react/src/App.tsx b/packages/e2e-react/src/App.tsx index 80f8e5f881..5be050dd0a 100644 --- a/packages/e2e-react/src/App.tsx +++ b/packages/e2e-react/src/App.tsx @@ -2,7 +2,13 @@ import { EmbeddedChat } from "@embeddedchat/react"; function App() { - return ; + return ( + + ); } export default App; diff --git a/packages/e2e-react/tests/auth.setup.ts b/packages/e2e-react/tests/auth.setup.ts index 57cd5e3b4c..90fc7ac8cd 100644 --- a/packages/e2e-react/tests/auth.setup.ts +++ b/packages/e2e-react/tests/auth.setup.ts @@ -1,21 +1,16 @@ import { test as setup, expect } from '@playwright/test'; -import { getIframe } from './helpers'; -import dotenv from 'dotenv'; - -dotenv.config(); -const authFile = '.auth/user.json'; +import { AUTH_FILE_PATH, TEST_PASSWORD, TEST_USERNAME } from '../constants'; setup('authenticate', async ({ page }) => { await page.goto('/'); - const iframe = await getIframe(page); - await iframe.getByTestId('join-button').click(); + await page.getByTestId('join-button').click(); - await iframe.getByTestId('login-email').fill(process.env.USERNAME || ''); - await iframe.getByTestId('login-password').fill(process.env.PASSWORD || ''); + await page.getByTestId('login-email').fill(TEST_USERNAME); + await page.getByTestId('login-password').fill(TEST_PASSWORD); - await iframe.getByTestId('login-button').click(); - await expect(iframe.getByTestId('join-button')).toBeHidden(); + await page.getByTestId('login-button').click(); + await expect(page.getByTestId('join-button')).toBeHidden(); - await page.context().storageState({ path: authFile }); + await page.context().storageState({ path: AUTH_FILE_PATH }); }); diff --git a/packages/e2e-react/tests/example.spec.ts b/packages/e2e-react/tests/example.spec.ts index 19dfdc1b2b..2052bd56c6 100644 --- a/packages/e2e-react/tests/example.spec.ts +++ b/packages/e2e-react/tests/example.spec.ts @@ -1,12 +1,9 @@ import { test, expect } from '@playwright/test'; -import { getIframe } from './helpers'; test.beforeEach('open page', async ({ page }) => { await page.goto('/'); }); test('EmbeddedChat should render', async ({ page }) => { - const iframe = await getIframe(page); - - await expect(iframe.getByTestId('embedded-chat')).toBeVisible(); + await expect(page.getByTestId('embedded-chat')).toBeVisible(); }); diff --git a/packages/e2e-react/tests/helpers.ts b/packages/e2e-react/tests/helpers.ts deleted file mode 100644 index 0b83edbb87..0000000000 --- a/packages/e2e-react/tests/helpers.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { Page } from "@playwright/test"; - -export async function getIframe(page: Page) { - const iframe = page.frame({ name: 'storybook-preview-iframe' }); - if (!iframe) { - throw new Error('Could not find Storybook iframe'); - } - return iframe; -}