-
Notifications
You must be signed in to change notification settings - Fork 242
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
feat(test): Add Clerk Elements E2E #3394
Changes from all commits
66a39c8
89a9672
cca7d85
5a856c1
daf0d35
54250c0
be1c259
3072192
4ddd59a
06b9f18
fadbb73
6d10a92
1cbe092
db660b1
3a50509
a073298
a117759
ab29eff
c7359bc
ff3e23f
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 |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
'@clerk/elements': patch | ||
--- | ||
|
||
Update the TypeScript type of `<Input />` to allow the `validatePassword` prop also on `type="text"` (in addition to `type="password"`) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import { constants } from '../constants'; | ||
import { applicationConfig } from '../models/applicationConfig.js'; | ||
import { templates } from '../templates/index.js'; | ||
|
||
const clerkNextjsLocal = `file:${process.cwd()}/packages/nextjs`; | ||
const clerkElementsLocal = `file:${process.cwd()}/packages/elements`; | ||
|
||
const nextAppRouter = applicationConfig() | ||
.setName('elements-next') | ||
.useTemplate(templates['elements-next']) | ||
.setEnvFormatter('public', key => `NEXT_PUBLIC_${key}`) | ||
.addScript('setup', 'npm i') | ||
.addScript('dev', 'npm run dev') | ||
.addScript('build', 'npm run build') | ||
.addScript('serve', 'npm run start') | ||
.addDependency('next', constants.E2E_NEXTJS_VERSION) | ||
.addDependency('react', constants.E2E_REACT_VERSION) | ||
.addDependency('react-dom', constants.E2E_REACT_DOM_VERSION) | ||
.addDependency('@clerk/nextjs', constants.E2E_CLERK_VERSION || clerkNextjsLocal) | ||
.addDependency('@clerk/elements', constants.E2E_CLERK_VERSION || clerkElementsLocal); | ||
|
||
export const elements = { | ||
nextAppRouter, | ||
} as const; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
module.exports = { | ||
root: true, | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. | ||
|
||
# dependencies | ||
/node_modules | ||
/.pnp | ||
.pnp.js | ||
|
||
# testing | ||
/coverage | ||
|
||
# next.js | ||
/.next/ | ||
/out/ | ||
|
||
# production | ||
/build | ||
|
||
# misc | ||
.DS_Store | ||
*.pem | ||
|
||
# debug | ||
npm-debug.log* | ||
yarn-debug.log* | ||
yarn-error.log* | ||
|
||
# local env files | ||
.env*.local | ||
|
||
# vercel | ||
.vercel | ||
|
||
# typescript | ||
*.tsbuildinfo | ||
next-env.d.ts | ||
|
||
package-lock.json |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app). | ||
|
||
## Getting Started | ||
|
||
First, run the development server: | ||
|
||
```bash | ||
npm run dev | ||
# or | ||
yarn dev | ||
# or | ||
pnpm dev | ||
``` | ||
|
||
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. | ||
|
||
You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file. | ||
|
||
This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font. | ||
|
||
## Learn More | ||
|
||
To learn more about Next.js, take a look at the following resources: | ||
|
||
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. | ||
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. | ||
|
||
You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome! | ||
|
||
## Deploy on Vercel | ||
|
||
The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js. | ||
|
||
Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
/** @type {import('next').NextConfig} */ | ||
const nextConfig = { | ||
eslint: { | ||
ignoreDuringBuilds: true, | ||
}, | ||
}; | ||
|
||
module.exports = nextConfig; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
{ | ||
"name": "elements-next", | ||
"version": "0.1.0", | ||
"private": true, | ||
"scripts": { | ||
"build": "next build", | ||
"dev": "next dev", | ||
"lint": "next lint", | ||
"start": "next start" | ||
}, | ||
"dependencies": { | ||
"@clerk/elements": "file:../../../packages/elements", | ||
"@clerk/nextjs": "file:../../../packages/nextjs", | ||
"@types/node": "^18.17.0", | ||
"@types/react": "^18.3.1", | ||
"@types/react-dom": "^18.3.0", | ||
"next": "^14.2.3", | ||
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. ❓ shouldn't we use the 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. This can be handled with something like #3431 |
||
"react": "^18.3.1", | ||
"react-dom": "^18.3.1", | ||
"typescript": "^5.4.5" | ||
}, | ||
"devDependencies": { | ||
"autoprefixer": "^10.4.19", | ||
"postcss": "^8.4.38", | ||
"tailwindcss": "^3.4.3" | ||
}, | ||
"engines": { | ||
"node": ">=18.17.0" | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
module.exports = { | ||
plugins: { | ||
tailwindcss: {}, | ||
autoprefixer: {}, | ||
}, | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
@tailwind base; | ||
@tailwind components; | ||
@tailwind utilities; | ||
|
||
:root { | ||
--foreground-rgb: 0, 0, 0; | ||
--background-start-rgb: 214, 219, 220; | ||
--background-end-rgb: 255, 255, 255; | ||
} | ||
|
||
* { | ||
box-sizing: border-box; | ||
padding: 0; | ||
margin: 0; | ||
} | ||
|
||
html, | ||
body { | ||
max-width: 100vw; | ||
overflow-x: hidden; | ||
} | ||
|
||
body { | ||
color: rgb(var(--foreground-rgb)); | ||
background: linear-gradient(to bottom, transparent, rgb(var(--background-end-rgb))) rgb(var(--background-start-rgb)); | ||
font-family: -apple-system, BlinkMacSystemFont, avenir next, avenir, segoe ui, helvetica neue, helvetica, Cantarell, | ||
Ubuntu, roboto, noto, arial, sans-serif; | ||
} | ||
|
||
main { | ||
display: flex; | ||
flex-direction: column; | ||
justify-content: center; | ||
align-items: center; | ||
padding: 6rem; | ||
min-height: 100vh; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import './globals.css'; | ||
|
||
import { ClerkProvider } from '@clerk/nextjs'; | ||
import type { Metadata } from 'next'; | ||
|
||
export const metadata: Metadata = { | ||
title: 'Clerk Elements - Next.js E2E', | ||
description: 'Clerk Elements - Next.js E2E', | ||
}; | ||
|
||
export default function RootLayout({ children }: { children: React.ReactNode }) { | ||
return ( | ||
<html lang='en'> | ||
<ClerkProvider clerkJSVariant='headless'> | ||
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. ❓ Why 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. Right now the integration tests don't need the AIO components and eventually people should use headless, yes. |
||
<body>{children}</body> | ||
</ClerkProvider> | ||
</html> | ||
); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
'use client'; | ||
|
||
import * as Clerk from '@clerk/elements/common'; | ||
import * as SignIn from '@clerk/elements/sign-in'; | ||
|
||
function clsx(...args: (string | undefined | Record<string, boolean>)[]): string { | ||
const classes: string[] = []; | ||
|
||
for (const arg of args) { | ||
switch (typeof arg) { | ||
case 'string': | ||
classes.push(arg); | ||
break; | ||
case 'object': | ||
for (const key in arg) { | ||
if (arg[key]) { | ||
classes.push(key); | ||
} | ||
} | ||
break; | ||
} | ||
} | ||
|
||
return classes.join(' '); | ||
} | ||
|
||
export default function OTP() { | ||
return ( | ||
<main> | ||
<SignIn.Root path='/otp'> | ||
<SignIn.Step | ||
name='start' | ||
className='w-full space-y-6 rounded-2xl px-4 py-10 sm:w-96 sm:px-8 bg-white text-center shadow-md' | ||
> | ||
<header className='text-center'> | ||
<h1 className='text-xl font-medium tracking-tight text-neutral-950'>OTP Playground</h1> | ||
</header> | ||
<Clerk.Field | ||
name='simple-otp' | ||
className='space-y-2' | ||
> | ||
<Clerk.Label className='text-sm font-medium text-zinc-950'>Simple OTP Input</Clerk.Label> | ||
<Clerk.Input | ||
type='otp' | ||
className='w-full rounded-md bg-white px-3.5 py-2 text-sm outline-none ring-1 ring-inset ring-zinc-300 hover:ring-zinc-400 focus:ring-[1.5px] focus:ring-zinc-950 data-[invalid]:ring-red-400' | ||
data-testid='simple-otp' | ||
/> | ||
</Clerk.Field> | ||
<Clerk.Field | ||
name='segmented-otp' | ||
className='space-y-2' | ||
> | ||
<Clerk.Label className='text-sm font-medium text-zinc-950'>Segmented OTP Input</Clerk.Label> | ||
<Clerk.Input | ||
className='flex justify-center has-[:disabled]:opacity-50 segmented-otp-wrapper' | ||
type='otp' | ||
data-testid='segmented-otp' | ||
render={({ value, status, index }) => { | ||
return ( | ||
<div | ||
data-status={status} | ||
data-testid={`segmented-otp-${index}`} | ||
className={clsx( | ||
'relative flex size-10 items-center justify-center border-y border-r border-input text-sm transition-all first:rounded-l-md first:border-l last:rounded-r-md', | ||
{ | ||
'z-10 ring-2 ring-black ring-offset-black': status === 'cursor' || status === 'selected', | ||
}, | ||
)} | ||
> | ||
{value} | ||
{status === 'cursor' && ( | ||
<div className='pointer-events-none absolute inset-0 flex items-center justify-center'> | ||
<div className='animate-caret-blink h-4 w-px bg-black duration-1000' /> | ||
</div> | ||
)} | ||
</div> | ||
); | ||
}} | ||
/> | ||
</Clerk.Field> | ||
<Clerk.Field | ||
name='segmented-otp-with-props' | ||
className='space-y-2' | ||
> | ||
<Clerk.Label className='text-sm font-medium text-zinc-950'>Segmented OTP Input (with props)</Clerk.Label> | ||
<Clerk.Input | ||
className='flex justify-center has-[:disabled]:opacity-50 segmented-otp-with-props-wrapper' | ||
type='otp' | ||
data-testid='segmented-otp-with-props' | ||
passwordManagerOffset={4} | ||
length={4} | ||
render={({ value, status }) => { | ||
return ( | ||
<div | ||
data-status={status} | ||
className={clsx( | ||
'relative flex size-10 items-center justify-center border-y border-r border-input text-sm transition-all first:rounded-l-md first:border-l last:rounded-r-md', | ||
{ | ||
'z-10 ring-2 ring-black ring-offset-black': status === 'cursor' || status === 'selected', | ||
}, | ||
)} | ||
> | ||
{value} | ||
{status === 'cursor' && ( | ||
<div className='pointer-events-none absolute inset-0 flex items-center justify-center'> | ||
<div className='animate-caret-blink h-4 w-px bg-black duration-1000' /> | ||
</div> | ||
)} | ||
</div> | ||
); | ||
}} | ||
/> | ||
</Clerk.Field> | ||
</SignIn.Step> | ||
</SignIn.Root> | ||
</main> | ||
); | ||
} |
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.
☁️ I think we should drop the 2 lines above. We are not passing the deps added in presets in the package.json of the template in the other integration tests.
cc: @nikosdouvlis
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.
This way you can run the template locally just fine without needing to install them first. With
.addDependency
these entries are overwritten