-
Notifications
You must be signed in to change notification settings - Fork 3.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
chore(dashboard): user journey smoke tests #7124
base: next
Are you sure you want to change the base?
Changes from all commits
e12abe9
9f22ad5
d0a3333
ceabff2
8ad2e31
461275c
241dc38
1f5180e
ead9157
934a828
7bebc12
a7e8329
c253764
fa860f3
8c8cb67
ba8bf3a
ebc6c37
2f7b4cf
d7f56de
1aa027a
addf0fa
8a70a51
76c80c0
a1a5a6b
9c8f28c
674861a
5727282
5d0de32
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -28,4 +28,6 @@ tsconfig.node.tsbuildinfo | |
/test-results/ | ||
/playwright-report/ | ||
/blob-report/ | ||
/playwright/.cache/ | ||
/playwright/ | ||
.env.test | ||
.env.playwright | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,6 +5,7 @@ | |
"type": "module", | ||
"scripts": { | ||
"start": "vite", | ||
"start:test": "vite --mode test", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. run dashboard and use |
||
"start:static:build": "pm2 start proxy-server.js", | ||
"stop:static:build": "pm2 stop proxy-server.js", | ||
"dev": "pnpm start", | ||
|
@@ -92,9 +93,12 @@ | |
"zod": "^3.23.8" | ||
}, | ||
"devDependencies": { | ||
"@clerk/testing": "^1.3.27", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. used to initialize the Clerk session |
||
"@clerk/types": "^4.30.0", | ||
"@eslint/js": "^9.9.0", | ||
"@hookform/devtools": "^4.3.0", | ||
"@novu/dal": "workspace:*", | ||
"@novu/testing": "workspace:*", | ||
Comment on lines
+100
to
+101
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. used to initialize the api session |
||
"@playwright/test": "^1.44.0", | ||
"@sentry/vite-plugin": "^2.22.6", | ||
"@tiptap/core": "^2.10.3", | ||
|
@@ -106,6 +110,7 @@ | |
"@types/react-dom": "^18.3.0", | ||
"@vitejs/plugin-react": "^4.3.1", | ||
"autoprefixer": "^10.4.20", | ||
"dotenv": "^16.4.5", | ||
"eslint": "^9.9.0", | ||
"eslint-plugin-react-hooks": "^5.1.0-rc.0", | ||
"eslint-plugin-react-refresh": "^0.4.9", | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,9 +4,16 @@ 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') }); | ||
import dotenv from 'dotenv'; | ||
import path from 'path'; | ||
import { fileURLToPath } from 'url'; | ||
import { dirname } from 'path'; | ||
|
||
const fileName = fileURLToPath(import.meta.url); | ||
const dirName = dirname(fileName); | ||
dotenv.config({ path: path.resolve(dirName, '.env.playwright') }); | ||
Comment on lines
+12
to
+14
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Because the Dashboard project is configured with |
||
|
||
const baseURL = `http://localhost:4201`; | ||
|
||
/** | ||
* See https://playwright.dev/docs/test-configuration. | ||
|
@@ -24,9 +31,15 @@ export default defineConfig({ | |
/* Reporter to use. See https://playwright.dev/docs/test-reporters */ | ||
reporter: process.env.CI ? 'blob' : 'html', | ||
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */ | ||
webServer: { | ||
command: 'pnpm start:test', | ||
url: baseURL, | ||
timeout: 120 * 1000, | ||
reuseExistingServer: !process.env.CI, | ||
}, | ||
use: { | ||
/* Base URL to use in actions like `await page.goto('/')`. */ | ||
baseURL: 'http://127.0.0.1:8080', | ||
baseURL: baseURL, | ||
|
||
/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */ | ||
trace: 'on-first-retry', | ||
|
@@ -38,9 +51,22 @@ export default defineConfig({ | |
}, | ||
/* Configure projects for major browsers */ | ||
projects: [ | ||
{ | ||
name: 'setup', | ||
testMatch: /global\.setup\.ts/, | ||
}, | ||
Comment on lines
+54
to
+57
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The global setup test file will initialize the Clerk session for all tests. Using this approach, we can say that for some tests, we don't want to have a session, and then we will be able to verify, for example, the sign-in/up flows. |
||
{ | ||
name: 'chromium', | ||
use: { ...devices['Desktop Chrome'] }, | ||
use: { | ||
...devices['Desktop Chrome'], | ||
storageState: 'playwright/.clerk/user.json', | ||
viewport: { width: 1512, height: 982 }, | ||
video: { | ||
mode: 'on-first-retry', | ||
size: { width: 1512, height: 982 }, | ||
}, | ||
}, | ||
dependencies: ['setup'], | ||
}, | ||
], | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -78,8 +78,10 @@ const TagInput = forwardRef<HTMLInputElement, TagInputProps>((props, ref) => { | |
<div className="flex flex-wrap gap-2"> | ||
{tags.map((tag, index) => ( | ||
<Badge key={index} variant="outline" kind="tag" className="gap-1"> | ||
<span style={{ wordBreak: 'break-all' }}>{tag}</span> | ||
<button type="button" onClick={() => removeTag(tag)}> | ||
<span style={{ wordBreak: 'break-all' }} data-testid="tags-badge-value"> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For some components, I had to add |
||
{tag} | ||
</span> | ||
<button type="button" onClick={() => removeTag(tag)} data-testid={`tags-badge-remove-${tag}`}> | ||
<RiCloseFill className="-mr-0.5 size-3" /> | ||
<span className="sr-only">Remove tag</span> | ||
</button> | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
import { MODE } from '@/config'; | ||
|
||
// eslint-disable-next-line @typescript-eslint/no-namespace | ||
declare namespace Clerk { | ||
export const session: { | ||
|
@@ -6,5 +8,9 @@ declare namespace Clerk { | |
} | ||
|
||
export async function getToken(): Promise<string> { | ||
if (MODE === 'test') { | ||
return localStorage.getItem('nv_auth_token') ?? ''; | ||
} | ||
Comment on lines
+11
to
+13
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For tests, we store the API session-generated JWT token in the local storage because we don't use the one that is provided by the Clerk as the token signature won't match on the API, and we will not be able to authorize the requests. In short the |
||
|
||
return (await Clerk.session?.getToken()) || ''; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
.env.test
is the file for the Dashboard env variables