feat!: new server-only, faster and immediate autoLogin (#7224)
- When autoLogin is enabled, it will no longer flash an unresponsive "login" screen. Instead, it will straight up open the admin panel. That's because, on the server, we will now always & immediately see the user as authenticated, thus no initial login view is pushed to the client until the client component sends the auth request anymore. Less useless requests. Additionally, jwt verification is now completely skipped - No more auto-login related frontend code. autoLogin handling has been removed from the frontend `Auth` component - less code to maintain, this is way simpler now **For reviewers:** - The new logic for autoFill without prefillOnly is here: [jwt auth strategy](https://github.com/payloadcms/payload/pull/7224/files#diff-7d40839079a8b2abb58233e5904513ab321023a70538229dfaf1dfee067dc8bfR21) - The new logic for autoFill with prefillOnly is here: [Server Login View](https://github.com/payloadcms/payload/pull/7224/files#diff-683770104f196196743398a698fbf8987f00e4426ca1c0ace3658d18ab80e82dL72) => [Client Login Form](https://github.com/payloadcms/payload/pull/7224/files#diff-ac3504d3b3b0489455245663649bef9e84477bf0c1185da5a4d3a612450f01eeL20) **BREAKING** `autoLogin` without `prefillOnly` set now also affects graphQL/Rest operations. Only the user specified in `autoLogin` will be returned. Within the graphQL/Rest/Local API, this should still allow you to authenticate with a different user, as the autoLogin user is only used if no token is set.
This commit is contained in:
@@ -87,9 +87,9 @@ const config = buildConfig({
|
||||
The following options are available:
|
||||
|
||||
| Option | Description |
|
||||
| ----------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `autoLogin` | Used to automate admin log-in for dev and demonstration convenience. [More details](../authentication/overview). |
|
||||
|---------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| `avatar` | Set account profile picture. Options: `gravatar`, `default` or a custom React component. |
|
||||
| `autoLogin` | Used to automate log-in for dev and demonstration convenience. [More details](../authentication/overview). |
|
||||
| `buildPath` | Specify an absolute path for where to store the built Admin bundle used in production. Defaults to `path.resolve(process.cwd(), 'build')`. |
|
||||
| `components` | Component overrides that affect the entirety of the Admin Panel. [More details](./components). |
|
||||
| `custom` | Any custom properties you wish to pass to the Admin Panel. |
|
||||
|
||||
@@ -127,18 +127,16 @@ If set to `true`, users can log in with either their username or email address.
|
||||
|
||||
If set to `true`, an email address is required when creating a new user. If set to `false`, email is not required upon creation.
|
||||
|
||||
## Admin Auto-Login
|
||||
## Auto-Login
|
||||
|
||||
For testing and demo purposes you may want to skip forcing the admin user to login in order to access the [Admin Panel](../admin/overview). Typically, all users should be required to login to access the Admin Panel, however, you can speed up local development time by enabling auto-login.
|
||||
For testing and demo purposes you may want to skip forcing the user to login in order to access your application. Typically, all users should be required to login, however, you can speed up local development time by enabling auto-login.
|
||||
|
||||
To enable auto-login, set the `autoLogin` property in the [Admin Config](../configuration/admin):
|
||||
|
||||
```ts
|
||||
import { buildConfig } from 'payload/config'
|
||||
import { buildConfig } from 'payload'
|
||||
|
||||
export default buildConfig({
|
||||
// ...
|
||||
admin: {
|
||||
// ...
|
||||
// highlight-start
|
||||
autoLogin:
|
||||
@@ -150,7 +148,6 @@ export default buildConfig({
|
||||
}
|
||||
: false,
|
||||
// highlight-end
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
@@ -162,9 +159,10 @@ export default buildConfig({
|
||||
The following options are available:
|
||||
|
||||
| Option | Description |
|
||||
| ----------------- | --------------------------------------------------------------------------------------------------------------- |
|
||||
|-------------------|-----------------------------------------------------------------------------------------------------------------|
|
||||
| **`username`** | The username of the user to login as |
|
||||
| **`email`** | The email address of the user to login as |
|
||||
| **`password`** | The password of the user to login as |
|
||||
| **`password`** | The password of the user to login as. This is only needed if `prefillOnly` is set to true |
|
||||
| **`prefillOnly`** | If set to true, the login credentials will be prefilled but the user will still need to click the login button. |
|
||||
|
||||
## Operations
|
||||
|
||||
@@ -65,7 +65,7 @@ export default buildConfig({
|
||||
The following options are available:
|
||||
|
||||
| Option | Description |
|
||||
| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
|----------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| **`admin`** | The configuration options for the Admin Panel, including Custom Components, Live Preview, etc. [More details](../admin/overview#admin-options). |
|
||||
| **`bin`** | Register custom bin scripts for Payload to execute. |
|
||||
| **`editor`** | The Rich Text Editor which will be used by `richText` fields. [More details](../rich-text/overview). |
|
||||
|
||||
@@ -17,13 +17,15 @@ import { LoginField } from '../LoginField/index.js'
|
||||
import './index.scss'
|
||||
|
||||
export const LoginForm: React.FC<{
|
||||
prefillEmail?: string
|
||||
prefillPassword?: string
|
||||
prefillUsername?: string
|
||||
searchParams: { [key: string]: string | string[] | undefined }
|
||||
}> = ({ searchParams }) => {
|
||||
}> = ({ prefillEmail, prefillPassword, prefillUsername, searchParams }) => {
|
||||
const config = useConfig()
|
||||
|
||||
const {
|
||||
admin: {
|
||||
autoLogin,
|
||||
routes: { forgot: forgotRoute },
|
||||
user: userSlug,
|
||||
},
|
||||
@@ -45,27 +47,25 @@ export const LoginForm: React.FC<{
|
||||
|
||||
const { t } = useTranslation()
|
||||
|
||||
const prefillForm = autoLogin && autoLogin.prefillOnly
|
||||
|
||||
const initialState: FormState = {
|
||||
password: {
|
||||
initialValue: prefillForm ? autoLogin.password : undefined,
|
||||
initialValue: prefillPassword ?? undefined,
|
||||
valid: true,
|
||||
value: prefillForm ? autoLogin.password : undefined,
|
||||
value: prefillPassword ?? undefined,
|
||||
},
|
||||
}
|
||||
|
||||
if (loginWithUsername) {
|
||||
initialState.username = {
|
||||
initialValue: prefillForm ? autoLogin.username : undefined,
|
||||
initialValue: prefillUsername ?? undefined,
|
||||
valid: true,
|
||||
value: prefillForm ? autoLogin.username : undefined,
|
||||
value: prefillUsername ?? undefined,
|
||||
}
|
||||
} else {
|
||||
initialState.email = {
|
||||
initialValue: prefillForm ? autoLogin.email : undefined,
|
||||
initialValue: prefillEmail ?? undefined,
|
||||
valid: true,
|
||||
value: prefillForm ? autoLogin.email : undefined,
|
||||
value: prefillEmail ?? undefined,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -70,6 +70,24 @@ export const LoginView: React.FC<AdminViewProps> = ({ initPageResult, params, se
|
||||
|
||||
const collectionConfig = collections.find(({ slug }) => slug === userSlug)
|
||||
|
||||
const prefillAutoLogin =
|
||||
typeof config.admin?.autoLogin === 'object' && config.admin?.autoLogin.prefillOnly
|
||||
|
||||
const prefillUsername =
|
||||
prefillAutoLogin && typeof config.admin?.autoLogin === 'object'
|
||||
? config.admin?.autoLogin.username
|
||||
: undefined
|
||||
|
||||
const prefillEmail =
|
||||
prefillAutoLogin && typeof config.admin?.autoLogin === 'object'
|
||||
? config.admin?.autoLogin.email
|
||||
: undefined
|
||||
|
||||
const prefillPassword =
|
||||
prefillAutoLogin && typeof config.admin?.autoLogin === 'object'
|
||||
? config.admin?.autoLogin.password
|
||||
: undefined
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<div className={`${loginBaseClass}__brand`}>
|
||||
@@ -84,7 +102,14 @@ export const LoginView: React.FC<AdminViewProps> = ({ initPageResult, params, se
|
||||
/>
|
||||
</div>
|
||||
{Array.isArray(BeforeLogins) && BeforeLogins.map((Component) => Component)}
|
||||
{!collectionConfig?.auth?.disableLocalStrategy && <LoginForm searchParams={searchParams} />}
|
||||
{!collectionConfig?.auth?.disableLocalStrategy && (
|
||||
<LoginForm
|
||||
prefillEmail={prefillEmail}
|
||||
prefillPassword={prefillPassword}
|
||||
prefillUsername={prefillUsername}
|
||||
searchParams={searchParams}
|
||||
/>
|
||||
)}
|
||||
{Array.isArray(AfterLogins) && AfterLogins.map((Component) => Component)}
|
||||
</Fragment>
|
||||
)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import jwt from 'jsonwebtoken'
|
||||
|
||||
import type { Where } from '../../types/index.js'
|
||||
import type { AuthStrategyFunction, User } from '../index.js'
|
||||
|
||||
import { extractJWT } from '../extractJWT.js'
|
||||
@@ -16,6 +17,46 @@ export const JWTAuthentication: AuthStrategyFunction = async ({
|
||||
}) => {
|
||||
try {
|
||||
const token = extractJWT({ headers, payload })
|
||||
|
||||
if (
|
||||
!token &&
|
||||
typeof payload?.config?.admin?.autoLogin === 'object' &&
|
||||
!payload.config.admin?.autoLogin.prefillOnly &&
|
||||
headers.get('DisableAutologin') !== 'true'
|
||||
) {
|
||||
const collection = payload.collections[payload.config.admin.user]
|
||||
|
||||
const where: Where = {
|
||||
or: [],
|
||||
}
|
||||
if (payload.config.admin?.autoLogin.email) {
|
||||
where.or.push({
|
||||
email: {
|
||||
equals: payload.config.admin?.autoLogin.email,
|
||||
},
|
||||
})
|
||||
} else if (payload.config.admin?.autoLogin.username) {
|
||||
where.or.push({
|
||||
username: {
|
||||
equals: payload.config.admin?.autoLogin.username,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
const user = (
|
||||
await payload.find({
|
||||
collection: collection.config.slug,
|
||||
depth: isGraphQL ? 0 : collection.config.auth.depth,
|
||||
where,
|
||||
})
|
||||
).docs[0]
|
||||
user.collection = collection.config.slug
|
||||
user._strategy = 'local-jwt'
|
||||
return {
|
||||
user: user as User,
|
||||
}
|
||||
}
|
||||
|
||||
const decodedPayload = jwt.verify(token, payload.secret) as JWTToken & jwt.JwtPayload
|
||||
|
||||
const collection = payload.collections[decodedPayload.collection]
|
||||
|
||||
@@ -43,17 +43,7 @@ export type ClientConfig = {
|
||||
globals: ClientGlobalConfig[]
|
||||
} & Omit<SanitizedConfig, 'admin' | 'collections' | 'globals' | ServerOnlyRootProperties>
|
||||
|
||||
export const createClientConfig = async ({
|
||||
config,
|
||||
t,
|
||||
}: {
|
||||
config: SanitizedConfig
|
||||
t: TFunction
|
||||
// eslint-disable-next-line @typescript-eslint/require-await
|
||||
}): Promise<ClientConfig> => {
|
||||
const clientConfig: ClientConfig = { ...config }
|
||||
|
||||
const serverOnlyConfigProperties: Partial<ServerOnlyRootProperties>[] = [
|
||||
const serverOnlyConfigProperties: readonly Partial<ServerOnlyRootProperties>[] = [
|
||||
'endpoints',
|
||||
'db',
|
||||
'editor',
|
||||
@@ -72,30 +62,40 @@ export const createClientConfig = async ({
|
||||
// `admin`, `onInit`, `localization`, `collections`, and `globals` are all handled separately
|
||||
]
|
||||
|
||||
serverOnlyConfigProperties.forEach((key) => {
|
||||
const serverOnlyAdminProperties: readonly Partial<ServerOnlyRootAdminProperties>[] = ['components']
|
||||
|
||||
export const createClientConfig = async ({
|
||||
config,
|
||||
t,
|
||||
}: {
|
||||
config: SanitizedConfig
|
||||
t: TFunction
|
||||
// eslint-disable-next-line @typescript-eslint/require-await
|
||||
}): Promise<ClientConfig> => {
|
||||
const clientConfig: ClientConfig = { ...config }
|
||||
|
||||
for (const key of serverOnlyConfigProperties) {
|
||||
if (key in clientConfig) {
|
||||
delete clientConfig[key]
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
if ('localization' in clientConfig && clientConfig.localization) {
|
||||
clientConfig.localization = { ...clientConfig.localization }
|
||||
|
||||
clientConfig.localization.locales.forEach((locale) => {
|
||||
for (const locale of clientConfig.localization.locales) {
|
||||
delete locale.toString
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
if ('admin' in clientConfig) {
|
||||
clientConfig.admin = { ...clientConfig.admin }
|
||||
|
||||
const serverOnlyAdminProperties: Partial<ServerOnlyRootAdminProperties>[] = ['components']
|
||||
|
||||
serverOnlyAdminProperties.forEach((key) => {
|
||||
for (const key of serverOnlyAdminProperties) {
|
||||
if (key in clientConfig.admin) {
|
||||
delete clientConfig.admin[key]
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
if ('livePreview' in clientConfig.admin) {
|
||||
clientConfig.admin.livePreview = { ...clientConfig.admin.livePreview }
|
||||
|
||||
@@ -453,16 +453,15 @@ export type CORSConfig = {
|
||||
export type Config = {
|
||||
/** Configure admin dashboard */
|
||||
admin?: {
|
||||
/** Automatically log in as a user when visiting the admin dashboard. */
|
||||
/** Automatically log in as a user */
|
||||
autoLogin?:
|
||||
| {
|
||||
/**
|
||||
* The email address of the user to login as
|
||||
*
|
||||
*/
|
||||
email?: string
|
||||
/** The password of the user to login as */
|
||||
password: string
|
||||
/** The password of the user to login as. This is only needed if `prefillOnly` is set to true */
|
||||
password?: string
|
||||
/**
|
||||
* If set to true, the login credentials will be prefilled but the user will still need to click the login button.
|
||||
*
|
||||
@@ -473,9 +472,9 @@ export type Config = {
|
||||
username?: string
|
||||
}
|
||||
| false
|
||||
|
||||
/** Set account profile picture. Options: gravatar, default or a custom React component. */
|
||||
avatar?: 'default' | 'gravatar' | React.ComponentType<any>
|
||||
|
||||
/**
|
||||
* Add extra and/or replace built-in components with custom components
|
||||
*
|
||||
|
||||
@@ -12,7 +12,6 @@ import { useDebounce } from '../../hooks/useDebounce.js'
|
||||
import { useTranslation } from '../../providers/Translation/index.js'
|
||||
import { requests } from '../../utilities/api.js'
|
||||
import { useConfig } from '../Config/index.js'
|
||||
import { useSearchParams } from '../SearchParams/index.js'
|
||||
|
||||
export type AuthContext<T = ClientUser> = {
|
||||
fetchFullUser: () => Promise<void>
|
||||
@@ -34,11 +33,9 @@ const Context = createContext({} as AuthContext)
|
||||
const maxTimeoutTime = 2147483647
|
||||
|
||||
export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
|
||||
const { searchParams } = useSearchParams()
|
||||
const [user, setUser] = useState<ClientUser | null>()
|
||||
const [tokenInMemory, setTokenInMemory] = useState<string>()
|
||||
const [tokenExpiration, setTokenExpiration] = useState<number>()
|
||||
const [strategy, setStrategy] = useState<string>()
|
||||
const pathname = usePathname()
|
||||
const router = useRouter()
|
||||
// const { code } = useLocale()
|
||||
@@ -48,9 +45,7 @@ export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children
|
||||
|
||||
const {
|
||||
admin: {
|
||||
autoLogin,
|
||||
routes: { inactivity: logoutInactivityRoute },
|
||||
routes: { login: loginRoute },
|
||||
user: userSlug,
|
||||
},
|
||||
routes: { admin, api },
|
||||
@@ -79,7 +74,6 @@ export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children
|
||||
const revokeTokenAndExpire = useCallback(() => {
|
||||
setTokenInMemory(undefined)
|
||||
setTokenExpiration(undefined)
|
||||
setStrategy(undefined)
|
||||
}, [])
|
||||
|
||||
const setTokenAndExpiration = useCallback(
|
||||
@@ -88,7 +82,6 @@ export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children
|
||||
if (token && json?.exp) {
|
||||
setTokenInMemory(token)
|
||||
setTokenExpiration(json.exp)
|
||||
if (json.strategy) setStrategy(json.strategy)
|
||||
} else {
|
||||
revokeTokenAndExpire()
|
||||
}
|
||||
@@ -215,36 +208,6 @@ export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children
|
||||
if (json?.token) {
|
||||
setTokenAndExpiration(json)
|
||||
}
|
||||
} else if (autoLogin && autoLogin.prefillOnly !== true) {
|
||||
// auto log-in with the provided autoLogin credentials. This is used in dev mode
|
||||
// so you don't have to log in over and over again
|
||||
const autoLoginResult = await requests.post(
|
||||
`${serverURL}${api}/${userSlug}${loginRoute}`,
|
||||
{
|
||||
body: JSON.stringify({
|
||||
email: autoLogin.email,
|
||||
password: autoLogin.password,
|
||||
username: autoLogin.username,
|
||||
}),
|
||||
headers: {
|
||||
'Accept-Language': i18n.language,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
},
|
||||
)
|
||||
if (autoLoginResult.status === 200) {
|
||||
const autoLoginJson = await autoLoginResult.json()
|
||||
setUser(autoLoginJson.user)
|
||||
if (autoLoginJson?.token) {
|
||||
setTokenAndExpiration(autoLoginJson)
|
||||
}
|
||||
router.replace(
|
||||
typeof searchParams['redirect'] === 'string' ? searchParams['redirect'] : admin,
|
||||
)
|
||||
} else {
|
||||
setUser(null)
|
||||
revokeTokenAndExpire()
|
||||
}
|
||||
} else {
|
||||
setUser(null)
|
||||
revokeTokenAndExpire()
|
||||
@@ -253,21 +216,7 @@ export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children
|
||||
} catch (e) {
|
||||
toast.error(`Fetching user failed: ${e.message}`)
|
||||
}
|
||||
}, [
|
||||
serverURL,
|
||||
api,
|
||||
userSlug,
|
||||
i18n.language,
|
||||
autoLogin,
|
||||
setTokenAndExpiration,
|
||||
router,
|
||||
searchParams,
|
||||
admin,
|
||||
revokeTokenAndExpire,
|
||||
strategy,
|
||||
tokenExpiration,
|
||||
loginRoute,
|
||||
])
|
||||
}, [serverURL, api, userSlug, i18n.language, setTokenAndExpiration, revokeTokenAndExpire])
|
||||
|
||||
// On mount, get user and set
|
||||
useEffect(() => {
|
||||
|
||||
@@ -4,7 +4,7 @@ import { expect, test } from '@playwright/test'
|
||||
import * as path from 'path'
|
||||
import { fileURLToPath } from 'url'
|
||||
|
||||
import { ensureAutoLoginAndCompilationIsDone, initPageConsoleErrorCatch } from '../helpers.js'
|
||||
import { ensureCompilationIsDone, initPageConsoleErrorCatch } from '../helpers.js'
|
||||
import { AdminUrlUtil } from '../helpers/adminUrlUtil.js'
|
||||
import { initPayloadE2ENoConfig } from '../helpers/initPayloadE2ENoConfig.js'
|
||||
import { TEST_TIMEOUT_LONG } from '../playwright.config.js'
|
||||
@@ -25,7 +25,7 @@ test.describe('Admin Panel', () => {
|
||||
const context = await browser.newContext()
|
||||
page = await context.newPage()
|
||||
initPageConsoleErrorCatch(page)
|
||||
await ensureAutoLoginAndCompilationIsDone({ page, serverURL })
|
||||
await ensureCompilationIsDone({ page, serverURL })
|
||||
})
|
||||
|
||||
test('example test', async () => {
|
||||
|
||||
@@ -16,6 +16,9 @@ export interface Config {
|
||||
'payload-preferences': PayloadPreference;
|
||||
'payload-migrations': PayloadMigration;
|
||||
};
|
||||
db: {
|
||||
defaultIDType: string;
|
||||
};
|
||||
globals: {
|
||||
menu: Menu;
|
||||
'custom-ts': CustomT;
|
||||
@@ -30,13 +33,16 @@ export interface UserAuthOperations {
|
||||
email: string;
|
||||
};
|
||||
login: {
|
||||
password: string;
|
||||
email: string;
|
||||
password: string;
|
||||
};
|
||||
registerFirstUser: {
|
||||
email: string;
|
||||
password: string;
|
||||
};
|
||||
unlock: {
|
||||
email: string;
|
||||
};
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
|
||||
@@ -16,7 +16,7 @@ import type {
|
||||
|
||||
import {
|
||||
closeNav,
|
||||
ensureAutoLoginAndCompilationIsDone,
|
||||
ensureCompilationIsDone,
|
||||
exactText,
|
||||
getAdminRoutes,
|
||||
initPageConsoleErrorCatch,
|
||||
@@ -92,7 +92,7 @@ describe('access control', () => {
|
||||
initPageConsoleErrorCatch(page)
|
||||
|
||||
await login({ page, serverURL })
|
||||
await ensureAutoLoginAndCompilationIsDone({ page, serverURL })
|
||||
await ensureCompilationIsDone({ page, serverURL })
|
||||
|
||||
const {
|
||||
admin: {
|
||||
|
||||
@@ -8,7 +8,7 @@ import type { Config, Geo, Post } from '../../payload-types.js'
|
||||
import {
|
||||
checkBreadcrumb,
|
||||
checkPageTitle,
|
||||
ensureAutoLoginAndCompilationIsDone,
|
||||
ensureCompilationIsDone,
|
||||
exactText,
|
||||
getAdminRoutes,
|
||||
initPageConsoleErrorCatch,
|
||||
@@ -103,7 +103,7 @@ describe('admin1', () => {
|
||||
snapshotKey: 'adminTests1',
|
||||
})
|
||||
|
||||
await ensureAutoLoginAndCompilationIsDone({ customAdminRoutes, page, serverURL })
|
||||
await ensureCompilationIsDone({ customAdminRoutes, page, serverURL })
|
||||
|
||||
adminRoutes = getAdminRoutes({ customAdminRoutes })
|
||||
|
||||
@@ -115,7 +115,7 @@ describe('admin1', () => {
|
||||
snapshotKey: 'adminTests1',
|
||||
})
|
||||
|
||||
await ensureAutoLoginAndCompilationIsDone({ customAdminRoutes, page, serverURL })
|
||||
await ensureCompilationIsDone({ customAdminRoutes, page, serverURL })
|
||||
})
|
||||
|
||||
describe('metadata', () => {
|
||||
@@ -294,14 +294,6 @@ describe('admin1', () => {
|
||||
await expect(() => expect(page.url()).not.toContain(loginURL)).toPass({
|
||||
timeout: POLL_TOPASS_TIMEOUT,
|
||||
})
|
||||
|
||||
// Ensure auto-login logged the user back in
|
||||
|
||||
await expect(() => expect(page.url()).toBe(`${serverURL}${adminRoutes.routes.admin}`)).toPass(
|
||||
{
|
||||
timeout: POLL_TOPASS_TIMEOUT,
|
||||
},
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ import * as qs from 'qs-esm'
|
||||
import type { Config, Geo, Post } from '../../payload-types.js'
|
||||
|
||||
import {
|
||||
ensureAutoLoginAndCompilationIsDone,
|
||||
ensureCompilationIsDone,
|
||||
exactText,
|
||||
getAdminRoutes,
|
||||
initPageConsoleErrorCatch,
|
||||
@@ -67,7 +67,7 @@ describe('admin2', () => {
|
||||
snapshotKey: 'adminTests2',
|
||||
})
|
||||
|
||||
await ensureAutoLoginAndCompilationIsDone({ customAdminRoutes, page, serverURL })
|
||||
await ensureCompilationIsDone({ customAdminRoutes, page, serverURL })
|
||||
|
||||
adminRoutes = getAdminRoutes({ customAdminRoutes })
|
||||
})
|
||||
@@ -77,7 +77,7 @@ describe('admin2', () => {
|
||||
snapshotKey: 'adminTests2',
|
||||
})
|
||||
|
||||
await ensureAutoLoginAndCompilationIsDone({ customAdminRoutes, page, serverURL })
|
||||
await ensureCompilationIsDone({ customAdminRoutes, page, serverURL })
|
||||
})
|
||||
|
||||
describe('custom CSS', () => {
|
||||
|
||||
@@ -30,6 +30,9 @@ export interface Config {
|
||||
'payload-preferences': PayloadPreference;
|
||||
'payload-migrations': PayloadMigration;
|
||||
};
|
||||
db: {
|
||||
defaultIDType: string;
|
||||
};
|
||||
globals: {
|
||||
'hidden-global': HiddenGlobal;
|
||||
'global-no-api-view': GlobalNoApiView;
|
||||
@@ -49,13 +52,16 @@ export interface UserAuthOperations {
|
||||
email: string;
|
||||
};
|
||||
login: {
|
||||
password: string;
|
||||
email: string;
|
||||
password: string;
|
||||
};
|
||||
registerFirstUser: {
|
||||
email: string;
|
||||
password: string;
|
||||
};
|
||||
unlock: {
|
||||
email: string;
|
||||
};
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
|
||||
@@ -12,7 +12,7 @@ import type { PayloadTestSDK } from '../helpers/sdk/index.js'
|
||||
import type { Config } from './payload-types.js'
|
||||
|
||||
import {
|
||||
ensureAutoLoginAndCompilationIsDone,
|
||||
ensureCompilationIsDone,
|
||||
getAdminRoutes,
|
||||
initPageConsoleErrorCatch,
|
||||
saveDocAndAssert,
|
||||
@@ -105,7 +105,7 @@ describe('auth', () => {
|
||||
enableAPIKey: true,
|
||||
},
|
||||
})
|
||||
await ensureAutoLoginAndCompilationIsDone({ page, serverURL })
|
||||
await ensureCompilationIsDone({ page, serverURL })
|
||||
})
|
||||
|
||||
describe('authenticated users', () => {
|
||||
|
||||
@@ -179,15 +179,16 @@ export async function buildConfigWithDefaults(
|
||||
},
|
||||
}
|
||||
|
||||
config.admin = {
|
||||
autoLogin:
|
||||
if (!config.admin) {
|
||||
config.admin = {}
|
||||
}
|
||||
if (config.admin.autoLogin === undefined) {
|
||||
config.admin.autoLogin =
|
||||
process.env.PAYLOAD_PUBLIC_DISABLE_AUTO_LOGIN === 'true'
|
||||
? false
|
||||
: {
|
||||
email: 'dev@payloadcms.com',
|
||||
password: 'test',
|
||||
},
|
||||
...(config.admin || {}),
|
||||
}
|
||||
}
|
||||
|
||||
if (process.env.PAYLOAD_DISABLE_ADMIN === 'true') {
|
||||
|
||||
@@ -5,11 +5,7 @@ import { AdminUrlUtil } from 'helpers/adminUrlUtil.js'
|
||||
import path from 'path'
|
||||
import { fileURLToPath } from 'url'
|
||||
|
||||
import {
|
||||
ensureAutoLoginAndCompilationIsDone,
|
||||
initPageConsoleErrorCatch,
|
||||
saveDocAndAssert,
|
||||
} from '../helpers.js'
|
||||
import { ensureCompilationIsDone, initPageConsoleErrorCatch, saveDocAndAssert } from '../helpers.js'
|
||||
import { initPayloadE2ENoConfig } from '../helpers/initPayloadE2ENoConfig.js'
|
||||
import { TEST_TIMEOUT_LONG } from '../playwright.config.js'
|
||||
import { slugs } from './shared.js'
|
||||
@@ -35,7 +31,7 @@ describe('field error states', () => {
|
||||
page = await context.newPage()
|
||||
initPageConsoleErrorCatch(page)
|
||||
|
||||
await ensureAutoLoginAndCompilationIsDone({ page, serverURL })
|
||||
await ensureCompilationIsDone({ page, serverURL })
|
||||
})
|
||||
|
||||
test('Remove row should remove error states from parent fields', async () => {
|
||||
|
||||
@@ -16,7 +16,7 @@ import type {
|
||||
} from './payload-types.js'
|
||||
|
||||
import {
|
||||
ensureAutoLoginAndCompilationIsDone,
|
||||
ensureCompilationIsDone,
|
||||
initPageConsoleErrorCatch,
|
||||
openCreateDocDrawer,
|
||||
openDocControls,
|
||||
@@ -67,7 +67,7 @@ describe('fields - relationship', () => {
|
||||
page = await context.newPage()
|
||||
|
||||
initPageConsoleErrorCatch(page)
|
||||
await ensureAutoLoginAndCompilationIsDone({ page, serverURL })
|
||||
await ensureCompilationIsDone({ page, serverURL })
|
||||
})
|
||||
|
||||
beforeEach(async () => {
|
||||
@@ -137,7 +137,7 @@ describe('fields - relationship', () => {
|
||||
},
|
||||
})) as any
|
||||
|
||||
await ensureAutoLoginAndCompilationIsDone({ page, serverURL })
|
||||
await ensureCompilationIsDone({ page, serverURL })
|
||||
})
|
||||
|
||||
test('should create relationship', async () => {
|
||||
|
||||
@@ -9,7 +9,7 @@ import type { PayloadTestSDK } from '../../../helpers/sdk/index.js'
|
||||
import type { Config } from '../../payload-types.js'
|
||||
|
||||
import {
|
||||
ensureAutoLoginAndCompilationIsDone,
|
||||
ensureCompilationIsDone,
|
||||
initPageConsoleErrorCatch,
|
||||
saveDocAndAssert,
|
||||
} from '../../../helpers.js'
|
||||
@@ -48,7 +48,7 @@ describe('Array', () => {
|
||||
snapshotKey: 'fieldsArrayTest',
|
||||
uploadsDir: path.resolve(dirname, './collections/Upload/uploads'),
|
||||
})
|
||||
await ensureAutoLoginAndCompilationIsDone({ page, serverURL })
|
||||
await ensureCompilationIsDone({ page, serverURL })
|
||||
})
|
||||
beforeEach(async () => {
|
||||
await reInitializeDB({
|
||||
@@ -63,7 +63,7 @@ describe('Array', () => {
|
||||
client = new RESTClient(null, { defaultSlug: 'users', serverURL })
|
||||
await client.login()
|
||||
|
||||
await ensureAutoLoginAndCompilationIsDone({ page, serverURL })
|
||||
await ensureCompilationIsDone({ page, serverURL })
|
||||
})
|
||||
|
||||
let url: AdminUrlUtil
|
||||
|
||||
@@ -5,7 +5,7 @@ import path from 'path'
|
||||
import { fileURLToPath } from 'url'
|
||||
|
||||
import {
|
||||
ensureAutoLoginAndCompilationIsDone,
|
||||
ensureCompilationIsDone,
|
||||
initPageConsoleErrorCatch,
|
||||
saveDocAndAssert,
|
||||
} from '../../../helpers.js'
|
||||
@@ -43,7 +43,7 @@ describe('Block fields', () => {
|
||||
snapshotKey: 'blockFieldsTest',
|
||||
uploadsDir: path.resolve(dirname, './collections/Upload/uploads'),
|
||||
})
|
||||
await ensureAutoLoginAndCompilationIsDone({ page, serverURL })
|
||||
await ensureCompilationIsDone({ page, serverURL })
|
||||
})
|
||||
beforeEach(async () => {
|
||||
await reInitializeDB({
|
||||
@@ -58,7 +58,7 @@ describe('Block fields', () => {
|
||||
client = new RESTClient(null, { defaultSlug: 'users', serverURL })
|
||||
await client.login()
|
||||
|
||||
await ensureAutoLoginAndCompilationIsDone({ page, serverURL })
|
||||
await ensureCompilationIsDone({ page, serverURL })
|
||||
})
|
||||
|
||||
let url: AdminUrlUtil
|
||||
|
||||
@@ -8,7 +8,7 @@ import type { PayloadTestSDK } from '../../../helpers/sdk/index.js'
|
||||
import type { Config } from '../../payload-types.js'
|
||||
|
||||
import {
|
||||
ensureAutoLoginAndCompilationIsDone,
|
||||
ensureCompilationIsDone,
|
||||
initPageConsoleErrorCatch,
|
||||
saveDocAndAssert,
|
||||
} from '../../../helpers.js'
|
||||
@@ -50,7 +50,7 @@ describe('Date', () => {
|
||||
snapshotKey: 'fieldsDateTest',
|
||||
uploadsDir: path.resolve(dirname, './collections/Upload/uploads'),
|
||||
})
|
||||
await ensureAutoLoginAndCompilationIsDone({ page, serverURL })
|
||||
await ensureCompilationIsDone({ page, serverURL })
|
||||
})
|
||||
beforeEach(async () => {
|
||||
await reInitializeDB({
|
||||
@@ -65,7 +65,7 @@ describe('Date', () => {
|
||||
client = new RESTClient(null, { defaultSlug: 'users', serverURL })
|
||||
await client.login()
|
||||
|
||||
await ensureAutoLoginAndCompilationIsDone({ page, serverURL })
|
||||
await ensureCompilationIsDone({ page, serverURL })
|
||||
})
|
||||
|
||||
test('should display formatted date in list view table cell', async () => {
|
||||
|
||||
@@ -11,7 +11,7 @@ import type { PayloadTestSDK } from '../../../../../helpers/sdk/index.js'
|
||||
import type { Config, LexicalField, Upload } from '../../../../payload-types.js'
|
||||
|
||||
import {
|
||||
ensureAutoLoginAndCompilationIsDone,
|
||||
ensureCompilationIsDone,
|
||||
initPageConsoleErrorCatch,
|
||||
saveDocAndAssert,
|
||||
} from '../../../../../helpers.js'
|
||||
@@ -74,7 +74,7 @@ describe('lexicalBlocks', () => {
|
||||
snapshotKey: 'fieldsLexicalBlocksTest',
|
||||
uploadsDir: path.resolve(dirname, './collections/Upload/uploads'),
|
||||
})
|
||||
await ensureAutoLoginAndCompilationIsDone({ page, serverURL })
|
||||
await ensureCompilationIsDone({ page, serverURL })
|
||||
})
|
||||
beforeEach(async () => {
|
||||
/*await throttleTest({
|
||||
|
||||
@@ -10,7 +10,7 @@ import type { PayloadTestSDK } from '../../../../../helpers/sdk/index.js'
|
||||
import type { Config, LexicalField } from '../../../../payload-types.js'
|
||||
|
||||
import {
|
||||
ensureAutoLoginAndCompilationIsDone,
|
||||
ensureCompilationIsDone,
|
||||
initPageConsoleErrorCatch,
|
||||
saveDocAndAssert,
|
||||
} from '../../../../../helpers.js'
|
||||
@@ -73,7 +73,7 @@ describe('lexicalMain', () => {
|
||||
snapshotKey: 'fieldsLexicalMainTest',
|
||||
uploadsDir: path.resolve(dirname, './collections/Upload/uploads'),
|
||||
})
|
||||
await ensureAutoLoginAndCompilationIsDone({ page, serverURL })
|
||||
await ensureCompilationIsDone({ page, serverURL })
|
||||
})
|
||||
beforeEach(async () => {
|
||||
/*await throttleTest({
|
||||
|
||||
@@ -9,7 +9,7 @@ import type { PayloadTestSDK } from '../../../helpers/sdk/index.js'
|
||||
import type { Config } from '../../payload-types.js'
|
||||
|
||||
import {
|
||||
ensureAutoLoginAndCompilationIsDone,
|
||||
ensureCompilationIsDone,
|
||||
initPageConsoleErrorCatch,
|
||||
saveDocAndAssert,
|
||||
} from '../../../helpers.js'
|
||||
@@ -51,7 +51,7 @@ describe('Number', () => {
|
||||
snapshotKey: 'fieldsNumberTest',
|
||||
uploadsDir: path.resolve(dirname, './collections/Upload/uploads'),
|
||||
})
|
||||
await ensureAutoLoginAndCompilationIsDone({ page, serverURL })
|
||||
await ensureCompilationIsDone({ page, serverURL })
|
||||
})
|
||||
beforeEach(async () => {
|
||||
await reInitializeDB({
|
||||
@@ -66,7 +66,7 @@ describe('Number', () => {
|
||||
client = new RESTClient(null, { defaultSlug: 'users', serverURL })
|
||||
await client.login()
|
||||
|
||||
await ensureAutoLoginAndCompilationIsDone({ page, serverURL })
|
||||
await ensureCompilationIsDone({ page, serverURL })
|
||||
})
|
||||
|
||||
test('should display field in list view', async () => {
|
||||
|
||||
@@ -8,7 +8,7 @@ import type { PayloadTestSDK } from '../../../helpers/sdk/index.js'
|
||||
import type { Config } from '../../payload-types.js'
|
||||
|
||||
import {
|
||||
ensureAutoLoginAndCompilationIsDone,
|
||||
ensureCompilationIsDone,
|
||||
initPageConsoleErrorCatch,
|
||||
saveDocAndAssert,
|
||||
} from '../../../helpers.js'
|
||||
@@ -51,7 +51,7 @@ describe('Point', () => {
|
||||
snapshotKey: 'fieldsPointTest',
|
||||
uploadsDir: path.resolve(dirname, './collections/Upload/uploads'),
|
||||
})
|
||||
await ensureAutoLoginAndCompilationIsDone({ page, serverURL })
|
||||
await ensureCompilationIsDone({ page, serverURL })
|
||||
})
|
||||
beforeEach(async () => {
|
||||
await reInitializeDB({
|
||||
@@ -66,7 +66,7 @@ describe('Point', () => {
|
||||
client = new RESTClient(null, { defaultSlug: 'users', serverURL })
|
||||
await client.login()
|
||||
|
||||
await ensureAutoLoginAndCompilationIsDone({ page, serverURL })
|
||||
await ensureCompilationIsDone({ page, serverURL })
|
||||
|
||||
filledGroupPoint = await payload.create({
|
||||
collection: pointFieldsSlug,
|
||||
|
||||
@@ -9,7 +9,7 @@ import type { PayloadTestSDK } from '../../../helpers/sdk/index.js'
|
||||
import type { Config, RelationshipField, TextField } from '../../payload-types.js'
|
||||
|
||||
import {
|
||||
ensureAutoLoginAndCompilationIsDone,
|
||||
ensureCompilationIsDone,
|
||||
exactText,
|
||||
initPageConsoleErrorCatch,
|
||||
openCreateDocDrawer,
|
||||
@@ -50,7 +50,7 @@ describe('relationship', () => {
|
||||
snapshotKey: 'fieldsRelationshipTest',
|
||||
uploadsDir: path.resolve(dirname, './collections/Upload/uploads'),
|
||||
})
|
||||
await ensureAutoLoginAndCompilationIsDone({ page, serverURL })
|
||||
await ensureCompilationIsDone({ page, serverURL })
|
||||
})
|
||||
beforeEach(async () => {
|
||||
await reInitializeDB({
|
||||
@@ -65,7 +65,7 @@ describe('relationship', () => {
|
||||
client = new RESTClient(null, { defaultSlug: 'users', serverURL })
|
||||
await client.login()
|
||||
|
||||
await ensureAutoLoginAndCompilationIsDone({ page, serverURL })
|
||||
await ensureCompilationIsDone({ page, serverURL })
|
||||
})
|
||||
|
||||
let url: AdminUrlUtil
|
||||
|
||||
@@ -6,7 +6,7 @@ import { wait } from 'payload/shared'
|
||||
import { fileURLToPath } from 'url'
|
||||
|
||||
import {
|
||||
ensureAutoLoginAndCompilationIsDone,
|
||||
ensureCompilationIsDone,
|
||||
initPageConsoleErrorCatch,
|
||||
saveDocAndAssert,
|
||||
} from '../../../helpers.js'
|
||||
@@ -43,7 +43,7 @@ describe('Rich Text', () => {
|
||||
snapshotKey: 'fieldsRichTextTest',
|
||||
uploadsDir: path.resolve(dirname, './collections/Upload/uploads'),
|
||||
})
|
||||
await ensureAutoLoginAndCompilationIsDone({ page, serverURL })
|
||||
await ensureCompilationIsDone({ page, serverURL })
|
||||
})
|
||||
beforeEach(async () => {
|
||||
await reInitializeDB({
|
||||
@@ -58,7 +58,7 @@ describe('Rich Text', () => {
|
||||
client = new RESTClient(null, { defaultSlug: 'users', serverURL })
|
||||
await client.login()
|
||||
|
||||
await ensureAutoLoginAndCompilationIsDone({ page, serverURL })
|
||||
await ensureCompilationIsDone({ page, serverURL })
|
||||
})
|
||||
|
||||
async function navigateToRichTextFields() {
|
||||
|
||||
@@ -9,7 +9,7 @@ import type { PayloadTestSDK } from '../../../helpers/sdk/index.js'
|
||||
import type { Config } from '../../payload-types.js'
|
||||
|
||||
import {
|
||||
ensureAutoLoginAndCompilationIsDone,
|
||||
ensureCompilationIsDone,
|
||||
initPageConsoleErrorCatch,
|
||||
navigateToListCellLink,
|
||||
saveDocAndAssert,
|
||||
@@ -53,7 +53,7 @@ describe('Tabs', () => {
|
||||
snapshotKey: 'fieldsTabsTest',
|
||||
uploadsDir: path.resolve(dirname, './collections/Upload/uploads'),
|
||||
})
|
||||
await ensureAutoLoginAndCompilationIsDone({ page, serverURL })
|
||||
await ensureCompilationIsDone({ page, serverURL })
|
||||
})
|
||||
beforeEach(async () => {
|
||||
await reInitializeDB({
|
||||
@@ -68,7 +68,7 @@ describe('Tabs', () => {
|
||||
client = new RESTClient(null, { defaultSlug: 'users', serverURL })
|
||||
await client.login()
|
||||
|
||||
await ensureAutoLoginAndCompilationIsDone({ page, serverURL })
|
||||
await ensureCompilationIsDone({ page, serverURL })
|
||||
})
|
||||
|
||||
test('should fill and retain a new value within a tab while switching tabs', async () => {
|
||||
|
||||
@@ -9,7 +9,7 @@ import type { PayloadTestSDK } from '../../../helpers/sdk/index.js'
|
||||
import type { Config } from '../../payload-types.js'
|
||||
|
||||
import {
|
||||
ensureAutoLoginAndCompilationIsDone,
|
||||
ensureCompilationIsDone,
|
||||
exactText,
|
||||
initPageConsoleErrorCatch,
|
||||
saveDocAndAssert,
|
||||
@@ -53,7 +53,7 @@ describe('Text', () => {
|
||||
snapshotKey: 'fieldsTextTest',
|
||||
uploadsDir: path.resolve(dirname, './collections/Upload/uploads'),
|
||||
})
|
||||
await ensureAutoLoginAndCompilationIsDone({ page, serverURL })
|
||||
await ensureCompilationIsDone({ page, serverURL })
|
||||
})
|
||||
beforeEach(async () => {
|
||||
await reInitializeDB({
|
||||
@@ -68,7 +68,7 @@ describe('Text', () => {
|
||||
client = new RESTClient(null, { defaultSlug: 'users', serverURL })
|
||||
await client.login()
|
||||
|
||||
await ensureAutoLoginAndCompilationIsDone({ page, serverURL })
|
||||
await ensureCompilationIsDone({ page, serverURL })
|
||||
})
|
||||
|
||||
test('should display field in list view', async () => {
|
||||
|
||||
@@ -9,7 +9,7 @@ import type { PayloadTestSDK } from '../../../helpers/sdk/index.js'
|
||||
import type { Config } from '../../payload-types.js'
|
||||
|
||||
import {
|
||||
ensureAutoLoginAndCompilationIsDone,
|
||||
ensureCompilationIsDone,
|
||||
initPageConsoleErrorCatch,
|
||||
openDocDrawer,
|
||||
saveDocAndAssert,
|
||||
@@ -52,7 +52,7 @@ describe('Upload', () => {
|
||||
snapshotKey: 'fieldsUploadTest',
|
||||
uploadsDir: path.resolve(dirname, './collections/Upload/uploads'),
|
||||
})
|
||||
await ensureAutoLoginAndCompilationIsDone({ page, serverURL })
|
||||
await ensureCompilationIsDone({ page, serverURL })
|
||||
})
|
||||
beforeEach(async () => {
|
||||
await reInitializeDB({
|
||||
@@ -67,7 +67,7 @@ describe('Upload', () => {
|
||||
client = new RESTClient(null, { defaultSlug: 'users', serverURL })
|
||||
await client.login()
|
||||
|
||||
await ensureAutoLoginAndCompilationIsDone({ page, serverURL })
|
||||
await ensureCompilationIsDone({ page, serverURL })
|
||||
})
|
||||
|
||||
async function uploadImage() {
|
||||
|
||||
@@ -8,11 +8,7 @@ import { fileURLToPath } from 'url'
|
||||
import type { PayloadTestSDK } from '../helpers/sdk/index.js'
|
||||
import type { Config } from './payload-types.js'
|
||||
|
||||
import {
|
||||
ensureAutoLoginAndCompilationIsDone,
|
||||
initPageConsoleErrorCatch,
|
||||
saveDocAndAssert,
|
||||
} from '../helpers.js'
|
||||
import { ensureCompilationIsDone, initPageConsoleErrorCatch, saveDocAndAssert } from '../helpers.js'
|
||||
import { AdminUrlUtil } from '../helpers/adminUrlUtil.js'
|
||||
import { initPayloadE2ENoConfig } from '../helpers/initPayloadE2ENoConfig.js'
|
||||
import { reInitializeDB } from '../helpers/reInitializeDB.js'
|
||||
@@ -53,7 +49,7 @@ describe('fields', () => {
|
||||
snapshotKey: 'fieldsTest',
|
||||
uploadsDir: path.resolve(dirname, './collections/Upload/uploads'),
|
||||
})
|
||||
await ensureAutoLoginAndCompilationIsDone({ page, serverURL })
|
||||
await ensureCompilationIsDone({ page, serverURL })
|
||||
})
|
||||
beforeEach(async () => {
|
||||
await reInitializeDB({
|
||||
@@ -68,7 +64,7 @@ describe('fields', () => {
|
||||
client = new RESTClient(null, { defaultSlug: 'users', serverURL })
|
||||
await client.login()
|
||||
|
||||
await ensureAutoLoginAndCompilationIsDone({ page, serverURL })
|
||||
await ensureCompilationIsDone({ page, serverURL })
|
||||
})
|
||||
|
||||
describe('indexed', () => {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -48,11 +48,11 @@ const networkConditions = {
|
||||
}
|
||||
|
||||
/**
|
||||
* Load admin panel and make sure autologin has passed before running tests
|
||||
* Ensure admin panel is loaded before running tests
|
||||
* @param page
|
||||
* @param serverURL
|
||||
*/
|
||||
export async function ensureAutoLoginAndCompilationIsDone({
|
||||
export async function ensureCompilationIsDone({
|
||||
customAdminRoutes,
|
||||
customRoutes,
|
||||
page,
|
||||
@@ -64,9 +64,6 @@ export async function ensureAutoLoginAndCompilationIsDone({
|
||||
serverURL: string
|
||||
}): Promise<void> {
|
||||
const {
|
||||
admin: {
|
||||
routes: { createFirstUser: createFirstUserRoute, login: loginRoute },
|
||||
},
|
||||
routes: { admin: adminRoute },
|
||||
} = getAdminRoutes({ customAdminRoutes, customRoutes })
|
||||
|
||||
@@ -79,16 +76,6 @@ export async function ensureAutoLoginAndCompilationIsDone({
|
||||
timeout: POLL_TOPASS_TIMEOUT,
|
||||
})
|
||||
|
||||
await expect(() => expect(page.url()).not.toContain(`${adminRoute}${loginRoute}`)).toPass({
|
||||
timeout: POLL_TOPASS_TIMEOUT,
|
||||
})
|
||||
|
||||
await expect(() =>
|
||||
expect(page.url()).not.toContain(`${adminRoute}${createFirstUserRoute}`),
|
||||
).toPass({
|
||||
timeout: POLL_TOPASS_TIMEOUT,
|
||||
})
|
||||
|
||||
await expect(page.locator('.dashboard__label').first()).toBeVisible()
|
||||
}
|
||||
|
||||
|
||||
@@ -85,6 +85,9 @@ export class NextRESTClient {
|
||||
if (options.auth !== false && this.token) {
|
||||
headers.set('Authorization', `JWT ${this.token}`)
|
||||
}
|
||||
if (options.auth === false) {
|
||||
headers.set('DisableAutologin', 'true')
|
||||
}
|
||||
|
||||
return headers
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ const { beforeAll, beforeEach, describe } = test
|
||||
import path from 'path'
|
||||
import { fileURLToPath } from 'url'
|
||||
|
||||
import { ensureAutoLoginAndCompilationIsDone, initPageConsoleErrorCatch } from '../helpers.js'
|
||||
import { ensureCompilationIsDone, initPageConsoleErrorCatch } from '../helpers.js'
|
||||
import { initPayloadE2ENoConfig } from '../helpers/initPayloadE2ENoConfig.js'
|
||||
import { reInitializeDB } from '../helpers/reInitializeDB.js'
|
||||
import { TEST_TIMEOUT_LONG } from '../playwright.config.js'
|
||||
@@ -39,7 +39,7 @@ describe('i18n', () => {
|
||||
serverURL,
|
||||
snapshotKey: 'i18nTests',
|
||||
})
|
||||
await ensureAutoLoginAndCompilationIsDone({ page, serverURL })
|
||||
await ensureCompilationIsDone({ page, serverURL })
|
||||
})
|
||||
beforeEach(async () => {
|
||||
await reInitializeDB({
|
||||
@@ -47,7 +47,7 @@ describe('i18n', () => {
|
||||
snapshotKey: 'i18nTests',
|
||||
})
|
||||
|
||||
await ensureAutoLoginAndCompilationIsDone({ page, serverURL })
|
||||
await ensureCompilationIsDone({ page, serverURL })
|
||||
})
|
||||
|
||||
test('ensure i18n labels and useTranslation hooks display correct translation', async () => {
|
||||
|
||||
@@ -5,7 +5,7 @@ import path from 'path'
|
||||
import { fileURLToPath } from 'url'
|
||||
|
||||
import {
|
||||
ensureAutoLoginAndCompilationIsDone,
|
||||
ensureCompilationIsDone,
|
||||
exactText,
|
||||
initPageConsoleErrorCatch,
|
||||
saveDocAndAssert,
|
||||
@@ -57,7 +57,7 @@ describe('Live Preview', () => {
|
||||
|
||||
initPageConsoleErrorCatch(page)
|
||||
|
||||
await ensureAutoLoginAndCompilationIsDone({ page, serverURL })
|
||||
await ensureCompilationIsDone({ page, serverURL })
|
||||
})
|
||||
|
||||
test('collection — has tab', async () => {
|
||||
|
||||
@@ -10,7 +10,7 @@ import type { Config, LocalizedPost } from './payload-types.js'
|
||||
|
||||
import {
|
||||
changeLocale,
|
||||
ensureAutoLoginAndCompilationIsDone,
|
||||
ensureCompilationIsDone,
|
||||
initPageConsoleErrorCatch,
|
||||
openDocControls,
|
||||
saveDocAndAssert,
|
||||
@@ -63,7 +63,7 @@ describe('Localization', () => {
|
||||
|
||||
initPageConsoleErrorCatch(page)
|
||||
|
||||
await ensureAutoLoginAndCompilationIsDone({ page, serverURL })
|
||||
await ensureCompilationIsDone({ page, serverURL })
|
||||
})
|
||||
|
||||
describe('localized text', () => {
|
||||
|
||||
@@ -11,6 +11,16 @@
|
||||
"test:int": "pnpm -C \"../\" run test:int",
|
||||
"typecheck": "pnpm turbo build --filter test && tsc --project tsconfig.typecheck.json"
|
||||
},
|
||||
"lint-staged": {
|
||||
"**/package.json": "sort-package-json",
|
||||
"*.{md,mdx,yml,json}": "prettier --write",
|
||||
"*.{js,jsx,ts,tsx}": [
|
||||
"prettier --write",
|
||||
"eslint --cache --fix"
|
||||
],
|
||||
"templates/website/**/*": "sh -c \"cd templates/website; pnpm install --ignore-workspace --frozen-lockfile; pnpm run lint --fix\"",
|
||||
"tsconfig.json": "node scripts/reset-tsconfig.js"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@aws-sdk/client-s3": "^3.525.0",
|
||||
"@lexical/headless": "0.16.1",
|
||||
|
||||
@@ -4,7 +4,7 @@ import { expect, test } from '@playwright/test'
|
||||
import * as path from 'path'
|
||||
import { fileURLToPath } from 'url'
|
||||
|
||||
import { ensureAutoLoginAndCompilationIsDone, saveDocAndAssert } from '../helpers.js'
|
||||
import { ensureCompilationIsDone, saveDocAndAssert } from '../helpers.js'
|
||||
import { AdminUrlUtil } from '../helpers/adminUrlUtil.js'
|
||||
import { initPayloadE2ENoConfig } from '../helpers/initPayloadE2ENoConfig.js'
|
||||
import { TEST_TIMEOUT_LONG } from '../playwright.config.js'
|
||||
@@ -24,7 +24,7 @@ test.describe('Admin Panel', () => {
|
||||
|
||||
const context = await browser.newContext()
|
||||
page = await context.newPage()
|
||||
await ensureAutoLoginAndCompilationIsDone({ page, serverURL })
|
||||
await ensureCompilationIsDone({ page, serverURL })
|
||||
})
|
||||
|
||||
test('should create file upload', async () => {
|
||||
|
||||
@@ -7,7 +7,7 @@ import { fileURLToPath } from 'url'
|
||||
import type { PayloadTestSDK } from '../helpers/sdk/index.js'
|
||||
import type { Config } from './payload-types.js'
|
||||
|
||||
import { ensureAutoLoginAndCompilationIsDone, initPageConsoleErrorCatch } from '../helpers.js'
|
||||
import { ensureCompilationIsDone, initPageConsoleErrorCatch } from '../helpers.js'
|
||||
import { AdminUrlUtil } from '../helpers/adminUrlUtil.js'
|
||||
import { initPayloadE2ENoConfig } from '../helpers/initPayloadE2ENoConfig.js'
|
||||
import { POLL_TOPASS_TIMEOUT, TEST_TIMEOUT_LONG } from '../playwright.config.js'
|
||||
@@ -35,7 +35,7 @@ test.describe('Form Builder', () => {
|
||||
page = await context.newPage()
|
||||
initPageConsoleErrorCatch(page)
|
||||
|
||||
await ensureAutoLoginAndCompilationIsDone({ page, serverURL })
|
||||
await ensureCompilationIsDone({ page, serverURL })
|
||||
})
|
||||
|
||||
test.describe('Forms collection', () => {
|
||||
|
||||
@@ -6,7 +6,7 @@ import { fileURLToPath } from 'url'
|
||||
|
||||
import type { Config, Page as PayloadPage } from './payload-types.js'
|
||||
|
||||
import { ensureAutoLoginAndCompilationIsDone, initPageConsoleErrorCatch } from '../helpers.js'
|
||||
import { ensureCompilationIsDone, initPageConsoleErrorCatch } from '../helpers.js'
|
||||
import { AdminUrlUtil } from '../helpers/adminUrlUtil.js'
|
||||
import { initPayloadE2ENoConfig } from '../helpers/initPayloadE2ENoConfig.js'
|
||||
import { TEST_TIMEOUT_LONG } from '../playwright.config.js'
|
||||
@@ -69,7 +69,7 @@ describe('Nested Docs Plugin', () => {
|
||||
})
|
||||
draftChildId = draftChildPage.id
|
||||
|
||||
await ensureAutoLoginAndCompilationIsDone({ page, serverURL })
|
||||
await ensureCompilationIsDone({ page, serverURL })
|
||||
})
|
||||
|
||||
describe('Core functionality', () => {
|
||||
|
||||
@@ -8,7 +8,7 @@ import { fileURLToPath } from 'url'
|
||||
|
||||
import type { Config, Page as PayloadPage } from './payload-types.js'
|
||||
|
||||
import { ensureAutoLoginAndCompilationIsDone, initPageConsoleErrorCatch } from '../helpers.js'
|
||||
import { ensureCompilationIsDone, initPageConsoleErrorCatch } from '../helpers.js'
|
||||
import { AdminUrlUtil } from '../helpers/adminUrlUtil.js'
|
||||
import { initPayloadE2ENoConfig } from '../helpers/initPayloadE2ENoConfig.js'
|
||||
import { TEST_TIMEOUT_LONG } from '../playwright.config.js'
|
||||
@@ -57,7 +57,7 @@ describe('SEO Plugin', () => {
|
||||
})) as unknown as PayloadPage
|
||||
id = createdPage.id
|
||||
|
||||
await ensureAutoLoginAndCompilationIsDone({ page, serverURL })
|
||||
await ensureCompilationIsDone({ page, serverURL })
|
||||
})
|
||||
|
||||
describe('Core functionality', () => {
|
||||
|
||||
@@ -10,7 +10,7 @@ import type { PayloadTestSDK } from '../helpers/sdk/index.js'
|
||||
import type { Config, Media } from './payload-types.js'
|
||||
|
||||
import {
|
||||
ensureAutoLoginAndCompilationIsDone,
|
||||
ensureCompilationIsDone,
|
||||
initPageConsoleErrorCatch,
|
||||
openDocDrawer,
|
||||
saveDocAndAssert,
|
||||
@@ -89,7 +89,7 @@ describe('uploads', () => {
|
||||
|
||||
audioDoc = findAudio.docs[0] as unknown as Media
|
||||
|
||||
await ensureAutoLoginAndCompilationIsDone({ page, serverURL })
|
||||
await ensureCompilationIsDone({ page, serverURL })
|
||||
})
|
||||
|
||||
test('should see upload filename in relation list', async () => {
|
||||
|
||||
@@ -35,7 +35,7 @@ import type { Config } from './payload-types.js'
|
||||
import { globalSlug } from '../admin/slugs.js'
|
||||
import {
|
||||
changeLocale,
|
||||
ensureAutoLoginAndCompilationIsDone,
|
||||
ensureCompilationIsDone,
|
||||
exactText,
|
||||
findTableCell,
|
||||
initPageConsoleErrorCatch,
|
||||
@@ -113,7 +113,7 @@ describe('versions', () => {
|
||||
snapshotKey: 'versionsTest',
|
||||
})
|
||||
|
||||
await ensureAutoLoginAndCompilationIsDone({ page, serverURL })
|
||||
await ensureCompilationIsDone({ page, serverURL })
|
||||
//await clearAndSeedEverything(payload)
|
||||
})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user