diff --git a/docs/admin/overview.mdx b/docs/admin/overview.mdx index f483a3bc13..137d3956e2 100644 --- a/docs/admin/overview.mdx +++ b/docs/admin/overview.mdx @@ -86,19 +86,19 @@ 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. | -| `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. | -| `dateFormat` | The date format that will be used for all dates within the Admin Panel. Any valid [date-fns](https://date-fns.org/) format pattern can be used. | -| `disable` | If set to `true`, the entire Admin Panel will be disabled. | -| `livePreview` | Enable real-time editing for instant visual feedback of your front-end application. [More details](../live-preview/overview). | -| `meta` | Base metadata to use for the Admin Panel. Included properties are `titleSuffix`, `icons`, and `openGraph`. Can be overridden on a per Collection or per Global basis. | -| `routes` | Replace built-in Admin Panel routes with your own custom routes. [More details](#customizing-routes). | -| `user` | The `slug` of the Collection that you want to allow to login to the Admin Panel. [More details](#the-admin-user-collection). | +| Option | Description | +|---------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `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. | +| `dateFormat` | The date format that will be used for all dates within the Admin Panel. Any valid [date-fns](https://date-fns.org/) format pattern can be used. | +| `disable` | If set to `true`, the entire Admin Panel will be disabled. | +| `livePreview` | Enable real-time editing for instant visual feedback of your front-end application. [More details](../live-preview/overview). | +| `meta` | Base metadata to use for the Admin Panel. Included properties are `titleSuffix`, `icons`, and `openGraph`. Can be overridden on a per Collection or per Global basis. | +| `routes` | Replace built-in Admin Panel routes with your own custom routes. [More details](#customizing-routes). | +| `user` | The `slug` of the Collection that you want to allow to login to the Admin Panel. [More details](#the-admin-user-collection). | Reminder: diff --git a/docs/authentication/overview.mdx b/docs/authentication/overview.mdx index 22bd60679d..e1c402949d 100644 --- a/docs/authentication/overview.mdx +++ b/docs/authentication/overview.mdx @@ -127,30 +127,27 @@ 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: - process.env.NEXT_PUBLIC_ENABLE_AUTOLOGIN === 'true' - ? { - email: 'test@example.com', - password: 'test', - prefillOnly: true, - } - : false, - // highlight-end - }, + // highlight-start + autoLogin: + process.env.NEXT_PUBLIC_ENABLE_AUTOLOGIN === 'true' + ? { + email: 'test@example.com', + password: 'test', + prefillOnly: true, + } + : 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 diff --git a/docs/configuration/overview.mdx b/docs/configuration/overview.mdx index 233d0dcc7b..487e6bb5aa 100644 --- a/docs/configuration/overview.mdx +++ b/docs/configuration/overview.mdx @@ -64,38 +64,38 @@ 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). | -| **`db`** \* | The Database Adapter which will be used by Payload. [More details](../database/overview). | -| **`serverURL`** | A string used to define the absolute URL of your app. This includes the protocol, for example `https://example.com`. No paths allowed, only protocol, domain and (optionally) port. | -| **`collections`** | An array of Collections for Payload to manage. [More details](./collections). | -| **`globals`** | An array of Globals for Payload to manage. [More details](./globals). | +| 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). | +| **`db`** \* | The Database Adapter which will be used by Payload. [More details](../database/overview). | +| **`serverURL`** | A string used to define the absolute URL of your app. This includes the protocol, for example `https://example.com`. No paths allowed, only protocol, domain and (optionally) port. | +| **`collections`** | An array of Collections for Payload to manage. [More details](./collections). | +| **`globals`** | An array of Globals for Payload to manage. [More details](./globals). | | **`cors`** | Cross-origin resource sharing (CORS) is a mechanism that accept incoming requests from given domains. You can also customize the `Access-Control-Allow-Headers` header. [More details](#cors). | -| **`localization`** | Opt-in to translate your content into multiple locales. [More details](./localization). | -| **`graphQL`** | Manage GraphQL-specific functionality, including custom queries and mutations, query complexity limits, etc. [More details](../graphql/overview#graphql-options). | -| **`cookiePrefix`** | A string that will be prefixed to all cookies that Payload sets. | -| **`csrf`** | A whitelist array of URLs to allow Payload to accept cookies from. [More details](../authentication/overview#csrf-protection). | -| **`defaultDepth`** | If a user does not specify `depth` while requesting a resource, this depth will be used. [More details](../queries/depth). | -| **`defaultMaxTextLength`** | The maximum allowed string length to be permitted application-wide. Helps to prevent malicious public document creation. | -| **`maxDepth`** | The maximum allowed depth to be permitted application-wide. This setting helps prevent against malicious queries. Defaults to `10`. [More details](../queries/depth). | -| **`indexSortableFields`** | Automatically index all sortable top-level fields in the database to improve sort performance and add database compatibility for Azure Cosmos and similar. | -| **`upload`** | Base Payload upload configuration. [More details](../upload/overview#payload-wide-upload-options). | -| **`routes`** | Control the routing structure that Payload binds itself to. [More details](../admin/overview#root-level-routes). | -| **`email`** | Configure the Email Adapter for Payload to use. [More details](../email/overview). | -| **`debug`** | Enable to expose more detailed error information. | -| **`telemetry`** | Disable Payload telemetry by passing `false`. [More details](#telemetry). | -| **`rateLimit`** | Control IP-based rate limiting for all Payload resources. Used to prevent DDoS attacks, etc. [More details](../production/preventing-abuse#rate-limiting-requests). | -| **`hooks`** | An array of Root Hooks. [More details](../hooks/overview). | -| **`plugins`** | An array of Plugins. [More details](../plugins/overview). | -| **`endpoints`** | An array of Custom Endpoints added to the Payload router. [More details](../rest-api/overview#custom-endpoints). | -| **`custom`** | Extension point for adding custom data (e.g. for plugins). | -| **`i18n`** | Internationalization configuration. Pass all i18n languages you'd like the admin UI to support. Defaults to English-only. [More details](./i18n). | -| **`secret`** \* | A secure, unguessable string that Payload will use for any encryption workflows - for example, password salt / hashing. | -| **`sharp`** | If you would like Payload to offer cropping, focal point selection, and automatic media resizing, install and pass the Sharp module to the config here. | -| **`typescript`** | Configure TypeScript settings here. [More details](#typescript). | +| **`localization`** | Opt-in to translate your content into multiple locales. [More details](./localization). | +| **`graphQL`** | Manage GraphQL-specific functionality, including custom queries and mutations, query complexity limits, etc. [More details](../graphql/overview#graphql-options). | +| **`cookiePrefix`** | A string that will be prefixed to all cookies that Payload sets. | +| **`csrf`** | A whitelist array of URLs to allow Payload to accept cookies from. [More details](../authentication/overview#csrf-protection). | +| **`defaultDepth`** | If a user does not specify `depth` while requesting a resource, this depth will be used. [More details](../queries/depth). | +| **`defaultMaxTextLength`** | The maximum allowed string length to be permitted application-wide. Helps to prevent malicious public document creation. | +| **`maxDepth`** | The maximum allowed depth to be permitted application-wide. This setting helps prevent against malicious queries. Defaults to `10`. [More details](../queries/depth). | +| **`indexSortableFields`** | Automatically index all sortable top-level fields in the database to improve sort performance and add database compatibility for Azure Cosmos and similar. | +| **`upload`** | Base Payload upload configuration. [More details](../upload/overview#payload-wide-upload-options). | +| **`routes`** | Control the routing structure that Payload binds itself to. [More details](../admin/overview#root-level-routes). | +| **`email`** | Configure the Email Adapter for Payload to use. [More details](../email/overview). | +| **`debug`** | Enable to expose more detailed error information. | +| **`telemetry`** | Disable Payload telemetry by passing `false`. [More details](#telemetry). | +| **`rateLimit`** | Control IP-based rate limiting for all Payload resources. Used to prevent DDoS attacks, etc. [More details](../production/preventing-abuse#rate-limiting-requests). | +| **`hooks`** | An array of Root Hooks. [More details](../hooks/overview). | +| **`plugins`** | An array of Plugins. [More details](../plugins/overview). | +| **`endpoints`** | An array of Custom Endpoints added to the Payload router. [More details](../rest-api/overview#custom-endpoints). | +| **`custom`** | Extension point for adding custom data (e.g. for plugins). | +| **`i18n`** | Internationalization configuration. Pass all i18n languages you'd like the admin UI to support. Defaults to English-only. [More details](./i18n). | +| **`secret`** \* | A secure, unguessable string that Payload will use for any encryption workflows - for example, password salt / hashing. | +| **`sharp`** | If you would like Payload to offer cropping, focal point selection, and automatic media resizing, install and pass the Sharp module to the config here. | +| **`typescript`** | Configure TypeScript settings here. [More details](#typescript). | _\* An asterisk denotes that a property is required._ diff --git a/packages/next/src/views/Login/LoginForm/index.tsx b/packages/next/src/views/Login/LoginForm/index.tsx index 0673c9397f..05aef5f60e 100644 --- a/packages/next/src/views/Login/LoginForm/index.tsx +++ b/packages/next/src/views/Login/LoginForm/index.tsx @@ -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, } } diff --git a/packages/next/src/views/Login/index.tsx b/packages/next/src/views/Login/index.tsx index be61f74ffc..827155f823 100644 --- a/packages/next/src/views/Login/index.tsx +++ b/packages/next/src/views/Login/index.tsx @@ -70,6 +70,24 @@ export const LoginView: React.FC = ({ 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 (
@@ -84,7 +102,14 @@ export const LoginView: React.FC = ({ initPageResult, params, se />
{Array.isArray(BeforeLogins) && BeforeLogins.map((Component) => Component)} - {!collectionConfig?.auth?.disableLocalStrategy && } + {!collectionConfig?.auth?.disableLocalStrategy && ( + + )} {Array.isArray(AfterLogins) && AfterLogins.map((Component) => Component)}
) diff --git a/packages/payload/src/auth/strategies/jwt.ts b/packages/payload/src/auth/strategies/jwt.ts index 2d77fba60c..7482c030ef 100644 --- a/packages/payload/src/auth/strategies/jwt.ts +++ b/packages/payload/src/auth/strategies/jwt.ts @@ -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] diff --git a/packages/payload/src/config/client.ts b/packages/payload/src/config/client.ts index 01fa5a3416..d9b23a235b 100644 --- a/packages/payload/src/config/client.ts +++ b/packages/payload/src/config/client.ts @@ -43,6 +43,27 @@ export type ClientConfig = { globals: ClientGlobalConfig[] } & Omit +const serverOnlyConfigProperties: readonly Partial[] = [ + 'endpoints', + 'db', + 'editor', + 'plugins', + 'sharp', + 'onInit', + 'secret', + 'hooks', + 'bin', + 'typescript', + 'cors', + 'csrf', + 'email', + 'custom', + 'graphQL', + // `admin`, `onInit`, `localization`, `collections`, and `globals` are all handled separately +] + +const serverOnlyAdminProperties: readonly Partial[] = ['components'] + export const createClientConfig = async ({ config, t, @@ -53,49 +74,28 @@ export const createClientConfig = async ({ }): Promise => { const clientConfig: ClientConfig = { ...config } - const serverOnlyConfigProperties: Partial[] = [ - 'endpoints', - 'db', - 'editor', - 'plugins', - 'sharp', - 'onInit', - 'secret', - 'hooks', - 'bin', - 'typescript', - 'cors', - 'csrf', - 'email', - 'custom', - 'graphQL', - // `admin`, `onInit`, `localization`, `collections`, and `globals` are all handled separately - ] - - serverOnlyConfigProperties.forEach((key) => { + 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[] = ['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 } diff --git a/packages/payload/src/config/types.ts b/packages/payload/src/config/types.ts index f7477d822f..3ac995bbfa 100644 --- a/packages/payload/src/config/types.ts +++ b/packages/payload/src/config/types.ts @@ -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 - /** * Add extra and/or replace built-in components with custom components * diff --git a/packages/ui/src/providers/Auth/index.tsx b/packages/ui/src/providers/Auth/index.tsx index 26d469e127..f60c8081ba 100644 --- a/packages/ui/src/providers/Auth/index.tsx +++ b/packages/ui/src/providers/Auth/index.tsx @@ -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 = { fetchFullUser: () => Promise @@ -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() const [tokenInMemory, setTokenInMemory] = useState() const [tokenExpiration, setTokenExpiration] = useState() - const [strategy, setStrategy] = useState() 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(() => { diff --git a/test/_community/e2e.spec.ts b/test/_community/e2e.spec.ts index ecff243e6c..35e1fb60df 100644 --- a/test/_community/e2e.spec.ts +++ b/test/_community/e2e.spec.ts @@ -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 () => { diff --git a/test/_community/payload-types.ts b/test/_community/payload-types.ts index a36155c548..bf1368e08e 100644 --- a/test/_community/payload-types.ts +++ b/test/_community/payload-types.ts @@ -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 diff --git a/test/access-control/e2e.spec.ts b/test/access-control/e2e.spec.ts index 6723042bef..9a2d356281 100644 --- a/test/access-control/e2e.spec.ts +++ b/test/access-control/e2e.spec.ts @@ -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: { diff --git a/test/admin/e2e/1/e2e.spec.ts b/test/admin/e2e/1/e2e.spec.ts index 81b92f1f4c..b858b5093f 100644 --- a/test/admin/e2e/1/e2e.spec.ts +++ b/test/admin/e2e/1/e2e.spec.ts @@ -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, - }, - ) }) }) diff --git a/test/admin/e2e/2/e2e.spec.ts b/test/admin/e2e/2/e2e.spec.ts index 0a1e50f845..c0b7db8dbc 100644 --- a/test/admin/e2e/2/e2e.spec.ts +++ b/test/admin/e2e/2/e2e.spec.ts @@ -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', () => { diff --git a/test/admin/payload-types.ts b/test/admin/payload-types.ts index d846d1db67..d13e671147 100644 --- a/test/admin/payload-types.ts +++ b/test/admin/payload-types.ts @@ -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 diff --git a/test/auth/e2e.spec.ts b/test/auth/e2e.spec.ts index f56137bf1e..4f46b329b9 100644 --- a/test/auth/e2e.spec.ts +++ b/test/auth/e2e.spec.ts @@ -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', () => { diff --git a/test/buildConfigWithDefaults.ts b/test/buildConfigWithDefaults.ts index 03da180f01..de7e0cd846 100644 --- a/test/buildConfigWithDefaults.ts +++ b/test/buildConfigWithDefaults.ts @@ -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') { diff --git a/test/field-error-states/e2e.spec.ts b/test/field-error-states/e2e.spec.ts index 3db45402e4..616270901e 100644 --- a/test/field-error-states/e2e.spec.ts +++ b/test/field-error-states/e2e.spec.ts @@ -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 () => { diff --git a/test/fields-relationship/e2e.spec.ts b/test/fields-relationship/e2e.spec.ts index 2f3cc781f4..efe892afb7 100644 --- a/test/fields-relationship/e2e.spec.ts +++ b/test/fields-relationship/e2e.spec.ts @@ -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 () => { diff --git a/test/fields/collections/Array/e2e.spec.ts b/test/fields/collections/Array/e2e.spec.ts index 4c46ecd26c..3e31bc581d 100644 --- a/test/fields/collections/Array/e2e.spec.ts +++ b/test/fields/collections/Array/e2e.spec.ts @@ -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 diff --git a/test/fields/collections/Blocks/e2e.spec.ts b/test/fields/collections/Blocks/e2e.spec.ts index 1e299a3088..db9e356c09 100644 --- a/test/fields/collections/Blocks/e2e.spec.ts +++ b/test/fields/collections/Blocks/e2e.spec.ts @@ -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 diff --git a/test/fields/collections/Date/e2e.spec.ts b/test/fields/collections/Date/e2e.spec.ts index 0f8b223c94..cbfa4a68e3 100644 --- a/test/fields/collections/Date/e2e.spec.ts +++ b/test/fields/collections/Date/e2e.spec.ts @@ -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 () => { diff --git a/test/fields/collections/Lexical/e2e/blocks/e2e.spec.ts b/test/fields/collections/Lexical/e2e/blocks/e2e.spec.ts index 3c9df3cefe..3b0dfdf7f2 100644 --- a/test/fields/collections/Lexical/e2e/blocks/e2e.spec.ts +++ b/test/fields/collections/Lexical/e2e/blocks/e2e.spec.ts @@ -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({ diff --git a/test/fields/collections/Lexical/e2e/main/e2e.spec.ts b/test/fields/collections/Lexical/e2e/main/e2e.spec.ts index 9368698c5a..63018010b2 100644 --- a/test/fields/collections/Lexical/e2e/main/e2e.spec.ts +++ b/test/fields/collections/Lexical/e2e/main/e2e.spec.ts @@ -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({ diff --git a/test/fields/collections/Number/e2e.spec.ts b/test/fields/collections/Number/e2e.spec.ts index 432cad6c62..8a1d7d7160 100644 --- a/test/fields/collections/Number/e2e.spec.ts +++ b/test/fields/collections/Number/e2e.spec.ts @@ -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 () => { diff --git a/test/fields/collections/Point/e2e.spec.ts b/test/fields/collections/Point/e2e.spec.ts index 598ade5591..82a9b8fdc3 100644 --- a/test/fields/collections/Point/e2e.spec.ts +++ b/test/fields/collections/Point/e2e.spec.ts @@ -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, diff --git a/test/fields/collections/Relationship/e2e.spec.ts b/test/fields/collections/Relationship/e2e.spec.ts index 59c4d982a6..53b39d2f9f 100644 --- a/test/fields/collections/Relationship/e2e.spec.ts +++ b/test/fields/collections/Relationship/e2e.spec.ts @@ -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 diff --git a/test/fields/collections/RichText/e2e.spec.ts b/test/fields/collections/RichText/e2e.spec.ts index 3dbad0b93c..39e6fd120b 100644 --- a/test/fields/collections/RichText/e2e.spec.ts +++ b/test/fields/collections/RichText/e2e.spec.ts @@ -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() { diff --git a/test/fields/collections/Tabs/e2e.spec.ts b/test/fields/collections/Tabs/e2e.spec.ts index 23f2325f81..549bbfd024 100644 --- a/test/fields/collections/Tabs/e2e.spec.ts +++ b/test/fields/collections/Tabs/e2e.spec.ts @@ -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 () => { diff --git a/test/fields/collections/Text/e2e.spec.ts b/test/fields/collections/Text/e2e.spec.ts index a6e7bed276..36ec866e4e 100644 --- a/test/fields/collections/Text/e2e.spec.ts +++ b/test/fields/collections/Text/e2e.spec.ts @@ -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 () => { diff --git a/test/fields/collections/Upload/e2e.spec.ts b/test/fields/collections/Upload/e2e.spec.ts index 77d679014a..0db10bbf0f 100644 --- a/test/fields/collections/Upload/e2e.spec.ts +++ b/test/fields/collections/Upload/e2e.spec.ts @@ -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() { diff --git a/test/fields/e2e.spec.ts b/test/fields/e2e.spec.ts index 782b669a79..a013bab6f5 100644 --- a/test/fields/e2e.spec.ts +++ b/test/fields/e2e.spec.ts @@ -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', () => { diff --git a/test/fields/payload-types.ts b/test/fields/payload-types.ts index 39e97d820f..48b322536e 100644 --- a/test/fields/payload-types.ts +++ b/test/fields/payload-types.ts @@ -12,1433 +12,1459 @@ */ export type BlockColumns = | { - text?: string | null + text?: string | null; subArray?: | { - requiredText: string - id?: string | null + requiredText: string; + id?: string | null; }[] - | null - id?: string | null + | null; + id?: string | null; }[] - | null + | null; export interface Config { + auth: { + users: UserAuthOperations; + }; collections: { - 'lexical-fields': LexicalField - 'lexical-migrate-fields': LexicalMigrateField - 'lexical-localized-fields': LexicalLocalizedField - users: User - 'array-fields': ArrayField - 'block-fields': BlockField - 'checkbox-fields': CheckboxField - 'code-fields': CodeField - 'collapsible-fields': CollapsibleField - 'conditional-logic': ConditionalLogic - 'date-fields': DateField - 'radio-fields': RadioField - 'group-fields': GroupField - 'row-fields': RowField - 'indexed-fields': IndexedField - 'json-fields': JsonField - 'number-fields': NumberField - 'point-fields': PointField - 'relationship-fields': RelationshipField - 'rich-text-fields': RichTextField - 'select-fields': SelectField - 'tabs-fields-2': TabsFields2 - 'tabs-fields': TabsField - 'text-fields': TextField - uploads: Upload - uploads2: Uploads2 - uploads3: Uploads3 - 'ui-fields': UiField - 'payload-preferences': PayloadPreference - 'payload-migrations': PayloadMigration - } + 'lexical-fields': LexicalField; + 'lexical-migrate-fields': LexicalMigrateField; + 'lexical-localized-fields': LexicalLocalizedField; + users: User; + 'array-fields': ArrayField; + 'block-fields': BlockField; + 'checkbox-fields': CheckboxField; + 'code-fields': CodeField; + 'collapsible-fields': CollapsibleField; + 'conditional-logic': ConditionalLogic; + 'date-fields': DateField; + 'radio-fields': RadioField; + 'group-fields': GroupField; + 'row-fields': RowField; + 'indexed-fields': IndexedField; + 'json-fields': JsonField; + 'number-fields': NumberField; + 'point-fields': PointField; + 'relationship-fields': RelationshipField; + 'rich-text-fields': RichTextField; + 'select-fields': SelectField; + 'tabs-fields-2': TabsFields2; + 'tabs-fields': TabsField; + 'text-fields': TextField; + uploads: Upload; + uploads2: Uploads2; + uploads3: Uploads3; + 'ui-fields': UiField; + 'payload-preferences': PayloadPreference; + 'payload-migrations': PayloadMigration; + }; + db: { + defaultIDType: string; + }; globals: { - tabsWithRichText: TabsWithRichText - } - locale: 'en' | 'es' + tabsWithRichText: TabsWithRichText; + }; + locale: 'en' | 'es'; user: User & { - collection: 'users' - } + collection: 'users'; + }; +} +export interface UserAuthOperations { + forgotPassword: { + email: string; + }; + login: { + email: string; + password: string; + }; + registerFirstUser: { + email: string; + password: string; + }; + unlock: { + email: string; + }; } /** * This interface was referenced by `Config`'s JSON-Schema * via the `definition` "lexical-fields". */ export interface LexicalField { - id: string - title: string + id: string; + title: string; lexicalSimple?: { root: { - type: string + type: string; children: { - type: string - version: number - [k: string]: unknown - }[] - direction: ('ltr' | 'rtl') | null - format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | '' - indent: number - version: number - } - [k: string]: unknown - } | null + type: string; + version: number; + [k: string]: unknown; + }[]; + direction: ('ltr' | 'rtl') | null; + format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | ''; + indent: number; + version: number; + }; + [k: string]: unknown; + } | null; lexicalWithBlocks: { root: { - type: string + type: string; children: { - type: string - version: number - [k: string]: unknown - }[] - direction: ('ltr' | 'rtl') | null - format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | '' - indent: number - version: number - } - [k: string]: unknown - } - lexicalWithBlocks_markdown?: string | null - updatedAt: string - createdAt: string + type: string; + version: number; + [k: string]: unknown; + }[]; + direction: ('ltr' | 'rtl') | null; + format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | ''; + indent: number; + version: number; + }; + [k: string]: unknown; + }; + lexicalWithBlocks_markdown?: string | null; + updatedAt: string; + createdAt: string; } /** * This interface was referenced by `Config`'s JSON-Schema * via the `definition` "lexical-migrate-fields". */ export interface LexicalMigrateField { - id: string - title: string + id: string; + title: string; lexicalWithLexicalPluginData?: { root: { - type: string + type: string; children: { - type: string - version: number - [k: string]: unknown - }[] - direction: ('ltr' | 'rtl') | null - format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | '' - indent: number - version: number - } - [k: string]: unknown - } | null + type: string; + version: number; + [k: string]: unknown; + }[]; + direction: ('ltr' | 'rtl') | null; + format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | ''; + indent: number; + version: number; + }; + [k: string]: unknown; + } | null; lexicalWithSlateData?: { root: { - type: string + type: string; children: { - type: string - version: number - [k: string]: unknown - }[] - direction: ('ltr' | 'rtl') | null - format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | '' - indent: number - version: number - } - [k: string]: unknown - } | null + type: string; + version: number; + [k: string]: unknown; + }[]; + direction: ('ltr' | 'rtl') | null; + format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | ''; + indent: number; + version: number; + }; + [k: string]: unknown; + } | null; lexicalSimple?: { root: { - type: string + type: string; children: { - type: string - version: number - [k: string]: unknown - }[] - direction: ('ltr' | 'rtl') | null - format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | '' - indent: number - version: number - } - [k: string]: unknown - } | null - lexicalSimple_html?: string | null + type: string; + version: number; + [k: string]: unknown; + }[]; + direction: ('ltr' | 'rtl') | null; + format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | ''; + indent: number; + version: number; + }; + [k: string]: unknown; + } | null; + lexicalSimple_html?: string | null; groupWithLexicalField?: { lexicalInGroupField?: { root: { - type: string + type: string; children: { - type: string - version: number - [k: string]: unknown - }[] - direction: ('ltr' | 'rtl') | null - format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | '' - indent: number - version: number - } - [k: string]: unknown - } | null - lexicalInGroupField_html?: string | null - } + type: string; + version: number; + [k: string]: unknown; + }[]; + direction: ('ltr' | 'rtl') | null; + format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | ''; + indent: number; + version: number; + }; + [k: string]: unknown; + } | null; + lexicalInGroupField_html?: string | null; + }; arrayWithLexicalField?: | { lexicalInArrayField?: { root: { - type: string + type: string; children: { - type: string - version: number - [k: string]: unknown - }[] - direction: ('ltr' | 'rtl') | null - format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | '' - indent: number - version: number - } - [k: string]: unknown - } | null - lexicalInArrayField_html?: string | null - id?: string | null + type: string; + version: number; + [k: string]: unknown; + }[]; + direction: ('ltr' | 'rtl') | null; + format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | ''; + indent: number; + version: number; + }; + [k: string]: unknown; + } | null; + lexicalInArrayField_html?: string | null; + id?: string | null; }[] - | null - updatedAt: string - createdAt: string + | null; + updatedAt: string; + createdAt: string; } /** * This interface was referenced by `Config`'s JSON-Schema * via the `definition` "lexical-localized-fields". */ export interface LexicalLocalizedField { - id: string - title: string + id: string; + title: string; lexicalBlocksSubLocalized?: { root: { - type: string + type: string; children: { - type: string - version: number - [k: string]: unknown - }[] - direction: ('ltr' | 'rtl') | null - format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | '' - indent: number - version: number - } - [k: string]: unknown - } | null + type: string; + version: number; + [k: string]: unknown; + }[]; + direction: ('ltr' | 'rtl') | null; + format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | ''; + indent: number; + version: number; + }; + [k: string]: unknown; + } | null; lexicalBlocksLocalized?: { root: { - type: string + type: string; children: { - type: string - version: number - [k: string]: unknown - }[] - direction: ('ltr' | 'rtl') | null - format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | '' - indent: number - version: number - } - [k: string]: unknown - } | null - updatedAt: string - createdAt: string + type: string; + version: number; + [k: string]: unknown; + }[]; + direction: ('ltr' | 'rtl') | null; + format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | ''; + indent: number; + version: number; + }; + [k: string]: unknown; + } | null; + updatedAt: string; + createdAt: string; } /** * This interface was referenced by `Config`'s JSON-Schema * via the `definition` "users". */ export interface User { - id: string - canViewConditionalField?: boolean | null - updatedAt: string - createdAt: string - email: string - resetPasswordToken?: string | null - resetPasswordExpiration?: string | null - salt?: string | null - hash?: string | null - loginAttempts?: number | null - lockUntil?: string | null - password?: string | null + id: string; + canViewConditionalField?: boolean | null; + updatedAt: string; + createdAt: string; + email: string; + resetPasswordToken?: string | null; + resetPasswordExpiration?: string | null; + salt?: string | null; + hash?: string | null; + loginAttempts?: number | null; + lockUntil?: string | null; + password?: string | null; } /** * This interface was referenced by `Config`'s JSON-Schema * via the `definition` "array-fields". */ export interface ArrayField { - id: string - title?: string | null + id: string; + title?: string | null; items: { - text: string - localizedText?: string | null + text: string; + localizedText?: string | null; subArray?: | { - text?: string | null - id?: string | null + text?: string | null; + id?: string | null; }[] - | null - id?: string | null - }[] + | null; + id?: string | null; + }[]; collapsedArray?: | { - text: string - id?: string | null + text: string; + id?: string | null; }[] - | null + | null; localized: { - text: string - id?: string | null - }[] + text: string; + id?: string | null; + }[]; readOnly?: | { - text?: string | null - id?: string | null + text?: string | null; + id?: string | null; }[] - | null + | null; potentiallyEmptyArray?: | { - text?: string | null + text?: string | null; groupInRow?: { - textInGroupInRow?: string | null - } - id?: string | null + textInGroupInRow?: string | null; + }; + id?: string | null; }[] - | null + | null; rowLabelAsComponent?: | { - title?: string | null - id?: string | null + title?: string | null; + id?: string | null; }[] - | null + | null; arrayWithMinRows?: | { - text?: string | null - id?: string | null + text?: string | null; + id?: string | null; }[] - | null + | null; disableSort?: | { - text: string - id?: string | null + text: string; + id?: string | null; }[] - | null - updatedAt: string - createdAt: string + | null; + updatedAt: string; + createdAt: string; } /** * This interface was referenced by `Config`'s JSON-Schema * via the `definition` "block-fields". */ export interface BlockField { - id: string + id: string; blocks: ( | { - text: string + text: string; richText?: | { - [k: string]: unknown + [k: string]: unknown; }[] - | null - id?: string | null - blockName?: string | null - blockType: 'content' + | null; + id?: string | null; + blockName?: string | null; + blockType: 'content'; } | { - number: number - id?: string | null - blockName?: string | null - blockType: 'number' + number: number; + id?: string | null; + blockName?: string | null; + blockType: 'number'; } | { subBlocks?: | ( | { - text: string - id?: string | null - blockName?: string | null - blockType: 'text' + text: string; + id?: string | null; + blockName?: string | null; + blockType: 'text'; } | { - number: number - id?: string | null - blockName?: string | null - blockType: 'number' + number: number; + id?: string | null; + blockName?: string | null; + blockType: 'number'; } )[] - | null - id?: string | null - blockName?: string | null - blockType: 'subBlocks' + | null; + id?: string | null; + blockName?: string | null; + blockType: 'subBlocks'; } | { - textInCollapsible?: string | null - textInRow?: string | null - id?: string | null - blockName?: string | null - blockType: 'tabs' + textInCollapsible?: string | null; + textInRow?: string | null; + id?: string | null; + blockName?: string | null; + blockType: 'tabs'; } - )[] + )[]; duplicate: ( | { - text: string + text: string; richText?: | { - [k: string]: unknown + [k: string]: unknown; }[] - | null - id?: string | null - blockName?: string | null - blockType: 'content' + | null; + id?: string | null; + blockName?: string | null; + blockType: 'content'; } | { - number: number - id?: string | null - blockName?: string | null - blockType: 'number' + number: number; + id?: string | null; + blockName?: string | null; + blockType: 'number'; } | { subBlocks?: | ( | { - text: string - id?: string | null - blockName?: string | null - blockType: 'text' + text: string; + id?: string | null; + blockName?: string | null; + blockType: 'text'; } | { - number: number - id?: string | null - blockName?: string | null - blockType: 'number' + number: number; + id?: string | null; + blockName?: string | null; + blockType: 'number'; } )[] - | null - id?: string | null - blockName?: string | null - blockType: 'subBlocks' + | null; + id?: string | null; + blockName?: string | null; + blockType: 'subBlocks'; } | { - textInCollapsible?: string | null - textInRow?: string | null - id?: string | null - blockName?: string | null - blockType: 'tabs' + textInCollapsible?: string | null; + textInRow?: string | null; + id?: string | null; + blockName?: string | null; + blockType: 'tabs'; } - )[] + )[]; collapsedByDefaultBlocks: ( | { - text: string + text: string; richText?: | { - [k: string]: unknown + [k: string]: unknown; }[] - | null - id?: string | null - blockName?: string | null - blockType: 'localizedContent' + | null; + id?: string | null; + blockName?: string | null; + blockType: 'localizedContent'; } | { - number: number - id?: string | null - blockName?: string | null - blockType: 'localizedNumber' + number: number; + id?: string | null; + blockName?: string | null; + blockType: 'localizedNumber'; } | { subBlocks?: | ( | { - text: string - id?: string | null - blockName?: string | null - blockType: 'text' + text: string; + id?: string | null; + blockName?: string | null; + blockType: 'text'; } | { - number: number - id?: string | null - blockName?: string | null - blockType: 'number' + number: number; + id?: string | null; + blockName?: string | null; + blockType: 'number'; } )[] - | null - id?: string | null - blockName?: string | null - blockType: 'localizedSubBlocks' + | null; + id?: string | null; + blockName?: string | null; + blockType: 'localizedSubBlocks'; } | { - textInCollapsible?: string | null - textInRow?: string | null - id?: string | null - blockName?: string | null - blockType: 'localizedTabs' + textInCollapsible?: string | null; + textInRow?: string | null; + id?: string | null; + blockName?: string | null; + blockType: 'localizedTabs'; } - )[] + )[]; disableSort: ( | { - text: string + text: string; richText?: | { - [k: string]: unknown + [k: string]: unknown; }[] - | null - id?: string | null - blockName?: string | null - blockType: 'localizedContent' + | null; + id?: string | null; + blockName?: string | null; + blockType: 'localizedContent'; } | { - number: number - id?: string | null - blockName?: string | null - blockType: 'localizedNumber' + number: number; + id?: string | null; + blockName?: string | null; + blockType: 'localizedNumber'; } | { subBlocks?: | ( | { - text: string - id?: string | null - blockName?: string | null - blockType: 'text' + text: string; + id?: string | null; + blockName?: string | null; + blockType: 'text'; } | { - number: number - id?: string | null - blockName?: string | null - blockType: 'number' + number: number; + id?: string | null; + blockName?: string | null; + blockType: 'number'; } )[] - | null - id?: string | null - blockName?: string | null - blockType: 'localizedSubBlocks' + | null; + id?: string | null; + blockName?: string | null; + blockType: 'localizedSubBlocks'; } | { - textInCollapsible?: string | null - textInRow?: string | null - id?: string | null - blockName?: string | null - blockType: 'localizedTabs' + textInCollapsible?: string | null; + textInRow?: string | null; + id?: string | null; + blockName?: string | null; + blockType: 'localizedTabs'; } - )[] + )[]; localizedBlocks: ( | { - text: string + text: string; richText?: | { - [k: string]: unknown + [k: string]: unknown; }[] - | null - id?: string | null - blockName?: string | null - blockType: 'localizedContent' + | null; + id?: string | null; + blockName?: string | null; + blockType: 'localizedContent'; } | { - number: number - id?: string | null - blockName?: string | null - blockType: 'localizedNumber' + number: number; + id?: string | null; + blockName?: string | null; + blockType: 'localizedNumber'; } | { subBlocks?: | ( | { - text: string - id?: string | null - blockName?: string | null - blockType: 'text' + text: string; + id?: string | null; + blockName?: string | null; + blockType: 'text'; } | { - number: number - id?: string | null - blockName?: string | null - blockType: 'number' + number: number; + id?: string | null; + blockName?: string | null; + blockType: 'number'; } )[] - | null - id?: string | null - blockName?: string | null - blockType: 'localizedSubBlocks' + | null; + id?: string | null; + blockName?: string | null; + blockType: 'localizedSubBlocks'; } | { - textInCollapsible?: string | null - textInRow?: string | null - id?: string | null - blockName?: string | null - blockType: 'localizedTabs' + textInCollapsible?: string | null; + textInRow?: string | null; + id?: string | null; + blockName?: string | null; + blockType: 'localizedTabs'; } - )[] + )[]; i18nBlocks?: | { - text?: string | null - id?: string | null - blockName?: string | null - blockType: 'text' + text?: string | null; + id?: string | null; + blockName?: string | null; + blockType: 'text'; }[] - | null + | null; blocksWithSimilarConfigs?: | ( | { items?: | { - title: string - id?: string | null + title: string; + id?: string | null; }[] - | null - id?: string | null - blockName?: string | null - blockType: 'block-a' + | null; + id?: string | null; + blockName?: string | null; + blockType: 'block-a'; } | { items?: | { - title2: string - id?: string | null + title2: string; + id?: string | null; }[] - | null - id?: string | null - blockName?: string | null - blockType: 'block-b' + | null; + id?: string | null; + blockName?: string | null; + blockType: 'block-b'; } | { group?: { - text?: string | null - } - id?: string | null - blockName?: string | null - blockType: 'group-block' + text?: string | null; + }; + id?: string | null; + blockName?: string | null; + blockType: 'group-block'; } )[] - | null + | null; blocksWithSimilarGroup?: | ( | { group?: { - text?: string | null - } - id?: string | null - blockName?: string | null - blockType: 'group-block' + text?: string | null; + }; + id?: string | null; + blockName?: string | null; + blockType: 'group-block'; } | { items?: | { - title2: string - id?: string | null + title2: string; + id?: string | null; }[] - | null - id?: string | null - blockName?: string | null - blockType: 'block-b' + | null; + id?: string | null; + blockName?: string | null; + blockType: 'block-b'; } )[] - | null + | null; blocksWithMinRows?: | { - blockTitle?: string | null - id?: string | null - blockName?: string | null - blockType: 'block' + blockTitle?: string | null; + id?: string | null; + blockName?: string | null; + blockType: 'block'; }[] - | null + | null; customBlocks?: | ( | { - block1Title?: string | null - id?: string | null - blockName?: string | null - blockType: 'block-1' + block1Title?: string | null; + id?: string | null; + blockName?: string | null; + blockType: 'block-1'; } | { - block2Title?: string | null - id?: string | null - blockName?: string | null - blockType: 'block-2' + block2Title?: string | null; + id?: string | null; + blockName?: string | null; + blockType: 'block-2'; } )[] - | null + | null; relationshipBlocks?: | { - relationship?: (string | null) | TextField - id?: string | null - blockName?: string | null - blockType: 'relationships' + relationship?: (string | null) | TextField; + id?: string | null; + blockName?: string | null; + blockType: 'relationships'; }[] - | null - updatedAt: string - createdAt: string + | null; + updatedAt: string; + createdAt: string; } /** * This interface was referenced by `Config`'s JSON-Schema * via the `definition` "text-fields". */ export interface TextField { - id: string - text: string - localizedText?: string | null - i18nText?: string | null - defaultString?: string | null - defaultEmptyString?: string | null - defaultFunction?: string | null - defaultAsync?: string | null - overrideLength?: string | null - fieldWithDefaultValue?: string | null - dependentOnFieldWithDefaultValue?: string | null - customLabel?: string | null - customError?: string | null - beforeAndAfterInput?: string | null - hasMany?: string[] | null - validatesHasMany?: string[] | null - localizedHasMany?: string[] | null - withMinRows?: string[] | null - withMaxRows?: string[] | null - disableListColumnText?: string | null - disableListFilterText?: string | null - updatedAt: string - createdAt: string + id: string; + text: string; + localizedText?: string | null; + i18nText?: string | null; + defaultString?: string | null; + defaultEmptyString?: string | null; + defaultFunction?: string | null; + defaultAsync?: string | null; + overrideLength?: string | null; + fieldWithDefaultValue?: string | null; + dependentOnFieldWithDefaultValue?: string | null; + customLabel?: string | null; + customError?: string | null; + beforeAndAfterInput?: string | null; + hasMany?: string[] | null; + validatesHasMany?: string[] | null; + localizedHasMany?: string[] | null; + withMinRows?: string[] | null; + withMaxRows?: string[] | null; + disableListColumnText?: string | null; + disableListFilterText?: string | null; + updatedAt: string; + createdAt: string; } /** * This interface was referenced by `Config`'s JSON-Schema * via the `definition` "checkbox-fields". */ export interface CheckboxField { - id: string - checkbox: boolean - updatedAt: string - createdAt: string + id: string; + checkbox: boolean; + updatedAt: string; + createdAt: string; } /** * This interface was referenced by `Config`'s JSON-Schema * via the `definition` "code-fields". */ export interface CodeField { - id: string - javascript?: string | null - typescript?: string | null - json?: string | null - html?: string | null - css?: string | null - updatedAt: string - createdAt: string + id: string; + javascript?: string | null; + typescript?: string | null; + json?: string | null; + html?: string | null; + css?: string | null; + updatedAt: string; + createdAt: string; } /** * This interface was referenced by `Config`'s JSON-Schema * via the `definition` "collapsible-fields". */ export interface CollapsibleField { - id: string - text: string + id: string; + text: string; group?: { - textWithinGroup?: string | null + textWithinGroup?: string | null; subGroup?: { - textWithinSubGroup?: string | null - } - } - someText?: string | null + textWithinSubGroup?: string | null; + }; + }; + someText?: string | null; group2?: { - textWithinGroup?: string | null + textWithinGroup?: string | null; subGroup?: { - textWithinSubGroup?: string | null - } - } - functionTitleField?: string | null - componentTitleField?: string | null - nestedTitle?: string | null + textWithinSubGroup?: string | null; + }; + }; + functionTitleField?: string | null; + componentTitleField?: string | null; + nestedTitle?: string | null; arrayWithCollapsibles?: | { - innerCollapsible?: string | null - id?: string | null + innerCollapsible?: string | null; + id?: string | null; }[] - | null - updatedAt: string - createdAt: string + | null; + updatedAt: string; + createdAt: string; } /** * This interface was referenced by `Config`'s JSON-Schema * via the `definition` "conditional-logic". */ export interface ConditionalLogic { - id: string - text: string - toggleField?: boolean | null - fieldToToggle?: string | null - userConditional?: string | null + id: string; + text: string; + toggleField?: boolean | null; + fieldToToggle?: string | null; + userConditional?: string | null; parentGroup?: { - enableParentGroupFields?: boolean | null - siblingField?: string | null - } - reliesOnParentGroup?: string | null - groupSelection?: ('group1' | 'group2') | null + enableParentGroupFields?: boolean | null; + siblingField?: string | null; + }; + reliesOnParentGroup?: string | null; + groupSelection?: ('group1' | 'group2') | null; group1?: { - group1Field?: string | null - } + group1Field?: string | null; + }; group2?: { - group2Field?: string | null - } - updatedAt: string - createdAt: string + group2Field?: string | null; + }; + updatedAt: string; + createdAt: string; } /** * This interface was referenced by `Config`'s JSON-Schema * via the `definition` "date-fields". */ export interface DateField { - id: string - default: string - timeOnly?: string | null - timeOnlyWithCustomFormat?: string | null - dayOnly?: string | null - dayAndTime?: string | null - monthOnly?: string | null - updatedAt: string - createdAt: string + id: string; + default: string; + timeOnly?: string | null; + timeOnlyWithCustomFormat?: string | null; + dayOnly?: string | null; + dayAndTime?: string | null; + monthOnly?: string | null; + updatedAt: string; + createdAt: string; } /** * This interface was referenced by `Config`'s JSON-Schema * via the `definition` "radio-fields". */ export interface RadioField { - id: string - radio?: ('one' | 'two' | 'three') | null - updatedAt: string - createdAt: string + id: string; + radio?: ('one' | 'two' | 'three') | null; + updatedAt: string; + createdAt: string; } /** * This interface was referenced by `Config`'s JSON-Schema * via the `definition` "group-fields". */ export interface GroupField { - id: string + id: string; group: { - text: string - defaultParent?: string | null - defaultChild?: string | null + text: string; + defaultParent?: string | null; + defaultChild?: string | null; subGroup?: { - textWithinGroup?: string | null + textWithinGroup?: string | null; arrayWithinGroup?: | { - textWithinArray?: string | null - id?: string | null + textWithinArray?: string | null; + id?: string | null; }[] - | null - } - } + | null; + }; + }; arrayOfGroups?: | { groupItem?: { - text?: string | null - } - id?: string | null + text?: string | null; + }; + id?: string | null; }[] - | null + | null; localizedGroup?: { - text?: string | null - } + text?: string | null; + }; potentiallyEmptyGroup?: { - text?: string | null - } + text?: string | null; + }; groupInRow?: { - field?: string | null - secondField?: string | null - thirdField?: string | null - } + field?: string | null; + secondField?: string | null; + thirdField?: string | null; + }; secondGroupInRow?: { - field?: string | null + field?: string | null; nestedGroup?: { - nestedField?: string | null - } - } + nestedField?: string | null; + }; + }; groups?: { groupInRow?: { - field?: string | null - secondField?: string | null - thirdField?: string | null - } + field?: string | null; + secondField?: string | null; + thirdField?: string | null; + }; secondGroupInRow?: { - field?: string | null + field?: string | null; nestedGroup?: { - nestedField?: string | null - } - } - } - updatedAt: string - createdAt: string + nestedField?: string | null; + }; + }; + }; + updatedAt: string; + createdAt: string; } /** * This interface was referenced by `Config`'s JSON-Schema * via the `definition` "row-fields". */ export interface RowField { - id: string - title: string - field_with_width_a?: string | null - field_with_width_b?: string | null - field_within_collapsible_a?: string | null - field_within_collapsible_b?: string | null - updatedAt: string - createdAt: string + id: string; + title: string; + field_with_width_a?: string | null; + field_with_width_b?: string | null; + field_within_collapsible_a?: string | null; + field_within_collapsible_b?: string | null; + updatedAt: string; + createdAt: string; } /** * This interface was referenced by `Config`'s JSON-Schema * via the `definition` "indexed-fields". */ export interface IndexedField { - id: string - text: string - uniqueText?: string | null - uniqueRequiredText: string - localizedUniqueRequiredText: string + id: string; + text: string; + uniqueText?: string | null; + uniqueRequiredText: string; + localizedUniqueRequiredText: string; /** * @minItems 2 * @maxItems 2 */ - point?: [number, number] | null + point?: [number, number] | null; group?: { - localizedUnique?: string | null - unique?: string | null + localizedUnique?: string | null; + unique?: string | null; /** * @minItems 2 * @maxItems 2 */ - point?: [number, number] | null - } - collapsibleLocalizedUnique?: string | null - collapsibleTextUnique?: string | null - updatedAt: string - createdAt: string + point?: [number, number] | null; + }; + collapsibleLocalizedUnique?: string | null; + collapsibleTextUnique?: string | null; + updatedAt: string; + createdAt: string; } /** * This interface was referenced by `Config`'s JSON-Schema * via the `definition` "json-fields". */ export interface JsonField { - id: string - json?: - | { - [k: string]: unknown - } - | unknown[] - | string - | number - | boolean - | null + id: string; + json?: { + foo?: 'bar' | 'foobar'; + number?: 10 | 5; + [k: string]: unknown; + }; group?: { jsonWithinGroup?: | { - [k: string]: unknown + [k: string]: unknown; } | unknown[] | string | number | boolean - | null - } - updatedAt: string - createdAt: string + | null; + }; + updatedAt: string; + createdAt: string; } /** * This interface was referenced by `Config`'s JSON-Schema * via the `definition` "number-fields". */ export interface NumberField { - id: string - number?: number | null - min?: number | null - max?: number | null - positiveNumber?: number | null - negativeNumber?: number | null - decimalMin?: number | null - decimalMax?: number | null - defaultNumber?: number | null - hasMany?: number[] | null - validatesHasMany?: number[] | null - localizedHasMany?: number[] | null - withMinRows?: number[] | null - updatedAt: string - createdAt: string + id: string; + number?: number | null; + min?: number | null; + max?: number | null; + positiveNumber?: number | null; + negativeNumber?: number | null; + decimalMin?: number | null; + decimalMax?: number | null; + defaultNumber?: number | null; + hasMany?: number[] | null; + validatesHasMany?: number[] | null; + localizedHasMany?: number[] | null; + withMinRows?: number[] | null; + updatedAt: string; + createdAt: string; } /** * This interface was referenced by `Config`'s JSON-Schema * via the `definition` "point-fields". */ export interface PointField { - id: string + id: string; /** * @minItems 2 * @maxItems 2 */ - point: [number, number] + point: [number, number]; /** * @minItems 2 * @maxItems 2 */ - localized?: [number, number] | null + localized?: [number, number] | null; group?: { /** * @minItems 2 * @maxItems 2 */ - point?: [number, number] | null - } - updatedAt: string - createdAt: string + point?: [number, number] | null; + }; + updatedAt: string; + createdAt: string; } /** * This interface was referenced by `Config`'s JSON-Schema * via the `definition` "relationship-fields". */ export interface RelationshipField { - id: string - text?: string | null + id: string; + text?: string | null; relationship: | { - relationTo: 'text-fields' - value: string | TextField + relationTo: 'text-fields'; + value: string | TextField; } | { - relationTo: 'array-fields' - value: string | ArrayField - } + relationTo: 'array-fields'; + value: string | ArrayField; + }; relationHasManyPolymorphic?: | ( | { - relationTo: 'text-fields' - value: string | TextField + relationTo: 'text-fields'; + value: string | TextField; } | { - relationTo: 'array-fields' - value: string | ArrayField + relationTo: 'array-fields'; + value: string | ArrayField; } )[] - | null - relationToSelf?: (string | null) | RelationshipField - relationToSelfSelectOnly?: (string | null) | RelationshipField - relationWithDynamicDefault?: (string | null) | User + | null; + relationToSelf?: (string | null) | RelationshipField; + relationToSelfSelectOnly?: (string | null) | RelationshipField; + relationWithDynamicDefault?: (string | null) | User; relationHasManyWithDynamicDefault?: { - relationTo: 'users' - value: string | User - } | null - relationshipWithMin?: (string | TextField)[] | null - relationshipWithMax?: (string | TextField)[] | null - relationshipHasMany?: (string | TextField)[] | null + relationTo: 'users'; + value: string | User; + } | null; + relationshipWithMin?: (string | TextField)[] | null; + relationshipWithMax?: (string | TextField)[] | null; + relationshipHasMany?: (string | TextField)[] | null; array?: | { - relationship?: (string | null) | TextField - id?: string | null + relationship?: (string | null) | TextField; + id?: string | null; }[] - | null + | null; relationshipWithMinRows?: | { - relationTo: 'text-fields' - value: string | TextField + relationTo: 'text-fields'; + value: string | TextField; }[] - | null - updatedAt: string - createdAt: string + | null; + updatedAt: string; + createdAt: string; } /** * This interface was referenced by `Config`'s JSON-Schema * via the `definition` "rich-text-fields". */ export interface RichTextField { - id: string - title: string + id: string; + title: string; lexicalCustomFields: { root: { - type: string + type: string; children: { - type: string - version: number - [k: string]: unknown - }[] - direction: ('ltr' | 'rtl') | null - format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | '' - indent: number - version: number - } - [k: string]: unknown - } - lexicalCustomFields_html?: string | null + type: string; + version: number; + [k: string]: unknown; + }[]; + direction: ('ltr' | 'rtl') | null; + format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | ''; + indent: number; + version: number; + }; + [k: string]: unknown; + }; + lexicalCustomFields_html?: string | null; lexical?: { root: { - type: string + type: string; children: { - type: string - version: number - [k: string]: unknown - }[] - direction: ('ltr' | 'rtl') | null - format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | '' - indent: number - version: number - } - [k: string]: unknown - } | null - selectHasMany?: ('one' | 'two' | 'three' | 'four' | 'five' | 'six')[] | null + type: string; + version: number; + [k: string]: unknown; + }[]; + direction: ('ltr' | 'rtl') | null; + format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | ''; + indent: number; + version: number; + }; + [k: string]: unknown; + } | null; + selectHasMany?: ('one' | 'two' | 'three' | 'four' | 'five' | 'six')[] | null; richText: { - [k: string]: unknown - }[] + [k: string]: unknown; + }[]; richTextCustomFields?: | { - [k: string]: unknown + [k: string]: unknown; }[] - | null + | null; richTextReadOnly?: | { - [k: string]: unknown + [k: string]: unknown; }[] - | null + | null; blocks?: | ( | { - text?: string | null - id?: string | null - blockName?: string | null - blockType: 'textBlock' + text?: string | null; + id?: string | null; + blockName?: string | null; + blockType: 'textBlock'; } | { text?: | { - [k: string]: unknown + [k: string]: unknown; }[] - | null - id?: string | null - blockName?: string | null - blockType: 'richTextBlock' + | null; + id?: string | null; + blockName?: string | null; + blockType: 'richTextBlock'; } )[] - | null - updatedAt: string - createdAt: string + | null; + updatedAt: string; + createdAt: string; } /** * This interface was referenced by `Config`'s JSON-Schema * via the `definition` "select-fields". */ export interface SelectField { - id: string - select?: ('one' | 'two' | 'three') | null - selectReadOnly?: ('one' | 'two' | 'three') | null - selectHasMany?: ('one' | 'two' | 'three' | 'four' | 'five' | 'six')[] | null - selectHasManyLocalized?: ('one' | 'two')[] | null - selectI18n?: ('one' | 'two' | 'three') | null - simple?: ('One' | 'Two' | 'Three') | null + id: string; + select?: ('one' | 'two' | 'three') | null; + selectReadOnly?: ('one' | 'two' | 'three') | null; + selectHasMany?: ('one' | 'two' | 'three' | 'four' | 'five' | 'six')[] | null; + selectHasManyLocalized?: ('one' | 'two')[] | null; + selectI18n?: ('one' | 'two' | 'three') | null; + simple?: ('One' | 'Two' | 'Three') | null; settings?: { - category?: ('a' | 'b')[] | null - } - updatedAt: string - createdAt: string + category?: ('a' | 'b')[] | null; + }; + updatedAt: string; + createdAt: string; } /** * This interface was referenced by `Config`'s JSON-Schema * via the `definition` "tabs-fields-2". */ export interface TabsFields2 { - id: string + id: string; tabsInArray?: | { - text?: string | null + text?: string | null; tab2?: { - text2?: string | null - } - id?: string | null + text2?: string | null; + }; + id?: string | null; }[] - | null - updatedAt: string - createdAt: string + | null; + updatedAt: string; + createdAt: string; } /** * This interface was referenced by `Config`'s JSON-Schema * via the `definition` "tabs-fields". */ export interface TabsField { - id: string - sidebarField?: string | null + id: string; + sidebarField?: string | null; array: { - text: string - id?: string | null - }[] + text: string; + id?: string | null; + }[]; blocks: ( | { - text: string + text: string; richText?: | { - [k: string]: unknown + [k: string]: unknown; }[] - | null - id?: string | null - blockName?: string | null - blockType: 'content' + | null; + id?: string | null; + blockName?: string | null; + blockType: 'content'; } | { - number: number - id?: string | null - blockName?: string | null - blockType: 'number' + number: number; + id?: string | null; + blockName?: string | null; + blockType: 'number'; } | { subBlocks?: | ( | { - text: string - id?: string | null - blockName?: string | null - blockType: 'text' + text: string; + id?: string | null; + blockName?: string | null; + blockType: 'text'; } | { - number: number - id?: string | null - blockName?: string | null - blockType: 'number' + number: number; + id?: string | null; + blockName?: string | null; + blockType: 'number'; } )[] - | null - id?: string | null - blockName?: string | null - blockType: 'subBlocks' + | null; + id?: string | null; + blockName?: string | null; + blockType: 'subBlocks'; } | { - textInCollapsible?: string | null - textInRow?: string | null - id?: string | null - blockName?: string | null - blockType: 'tabs' + textInCollapsible?: string | null; + textInRow?: string | null; + id?: string | null; + blockName?: string | null; + blockType: 'tabs'; } - )[] + )[]; group: { - number: number - } - textInRow: string - numberInRow: number + number: number; + }; + textInRow: string; + numberInRow: number; json?: | { - [k: string]: unknown + [k: string]: unknown; } | unknown[] | string | number | boolean - | null + | null; tab: { array: { - text: string - id?: string | null - }[] - text?: string | null - defaultValue?: string | null + text: string; + id?: string | null; + }[]; + text?: string | null; + defaultValue?: string | null; arrayInRow?: | { - textInArrayInRow?: string | null - id?: string | null + textInArrayInRow?: string | null; + id?: string | null; }[] - | null - } + | null; + }; namedTabWithDefaultValue?: { - defaultValue?: string | null - } + defaultValue?: string | null; + }; localizedTab?: { - text?: string | null - } + text?: string | null; + }; accessControlTab?: { - text?: string | null - } + text?: string | null; + }; hooksTab?: { - beforeValidate?: boolean | null - beforeChange?: boolean | null - afterChange?: boolean | null - afterRead?: boolean | null - } - textarea?: string | null - anotherText: string + beforeValidate?: boolean | null; + beforeChange?: boolean | null; + afterChange?: boolean | null; + afterRead?: boolean | null; + }; + textarea?: string | null; + anotherText: string; nestedTab?: { - text?: string | null - } - updatedAt: string - createdAt: string + text?: string | null; + }; + updatedAt: string; + createdAt: string; } /** * This interface was referenced by `Config`'s JSON-Schema * via the `definition` "uploads". */ export interface Upload { - id: string - text?: string | null - media?: string | Upload | null + id: string; + text?: string | null; + media?: string | Upload | null; richText?: { root: { - type: string + type: string; children: { - type: string - version: number - [k: string]: unknown - }[] - direction: ('ltr' | 'rtl') | null - format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | '' - indent: number - version: number - } - [k: string]: unknown - } | null - updatedAt: string - createdAt: string - url?: string | null - thumbnailURL?: string | null - filename?: string | null - mimeType?: string | null - filesize?: number | null - width?: number | null - height?: number | null - focalX?: number | null - focalY?: number | null + type: string; + version: number; + [k: string]: unknown; + }[]; + direction: ('ltr' | 'rtl') | null; + format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | ''; + indent: number; + version: number; + }; + [k: string]: unknown; + } | null; + updatedAt: string; + createdAt: string; + url?: string | null; + thumbnailURL?: string | null; + filename?: string | null; + mimeType?: string | null; + filesize?: number | null; + width?: number | null; + height?: number | null; + focalX?: number | null; + focalY?: number | null; } /** * This interface was referenced by `Config`'s JSON-Schema * via the `definition` "uploads2". */ export interface Uploads2 { - id: string - text?: string | null - media?: string | Uploads2 | null - updatedAt: string - createdAt: string - url?: string | null - thumbnailURL?: string | null - filename?: string | null - mimeType?: string | null - filesize?: number | null - width?: number | null - height?: number | null - focalX?: number | null - focalY?: number | null + id: string; + text?: string | null; + media?: string | Uploads2 | null; + updatedAt: string; + createdAt: string; + url?: string | null; + thumbnailURL?: string | null; + filename?: string | null; + mimeType?: string | null; + filesize?: number | null; + width?: number | null; + height?: number | null; + focalX?: number | null; + focalY?: number | null; } /** * This interface was referenced by `Config`'s JSON-Schema * via the `definition` "uploads3". */ export interface Uploads3 { - id: string - media?: string | Uploads3 | null + id: string; + media?: string | Uploads3 | null; richText?: { root: { - type: string + type: string; children: { - type: string - version: number - [k: string]: unknown - }[] - direction: ('ltr' | 'rtl') | null - format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | '' - indent: number - version: number - } - [k: string]: unknown - } | null - updatedAt: string - createdAt: string - url?: string | null - thumbnailURL?: string | null - filename?: string | null - mimeType?: string | null - filesize?: number | null - width?: number | null - height?: number | null - focalX?: number | null - focalY?: number | null + type: string; + version: number; + [k: string]: unknown; + }[]; + direction: ('ltr' | 'rtl') | null; + format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | ''; + indent: number; + version: number; + }; + [k: string]: unknown; + } | null; + updatedAt: string; + createdAt: string; + url?: string | null; + thumbnailURL?: string | null; + filename?: string | null; + mimeType?: string | null; + filesize?: number | null; + width?: number | null; + height?: number | null; + focalX?: number | null; + focalY?: number | null; } /** * This interface was referenced by `Config`'s JSON-Schema * via the `definition` "ui-fields". */ export interface UiField { - id: string - text: string - updatedAt: string - createdAt: string + id: string; + text: string; + updatedAt: string; + createdAt: string; } /** * This interface was referenced by `Config`'s JSON-Schema * via the `definition` "payload-preferences". */ export interface PayloadPreference { - id: string + id: string; user: { - relationTo: 'users' - value: string | User - } - key?: string | null + relationTo: 'users'; + value: string | User; + }; + key?: string | null; value?: | { - [k: string]: unknown + [k: string]: unknown; } | unknown[] | string | number | boolean - | null - updatedAt: string - createdAt: string + | null; + updatedAt: string; + createdAt: string; } /** * This interface was referenced by `Config`'s JSON-Schema * via the `definition` "payload-migrations". */ export interface PayloadMigration { - id: string - name?: string | null - batch?: number | null - updatedAt: string - createdAt: string + id: string; + name?: string | null; + batch?: number | null; + updatedAt: string; + createdAt: string; } /** * This interface was referenced by `Config`'s JSON-Schema * via the `definition` "tabsWithRichText". */ export interface TabsWithRichText { - id: string + id: string; tab1?: { rt1?: { root: { - type: string + type: string; children: { - type: string - version: number - [k: string]: unknown - }[] - direction: ('ltr' | 'rtl') | null - format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | '' - indent: number - version: number - } - [k: string]: unknown - } | null - } + type: string; + version: number; + [k: string]: unknown; + }[]; + direction: ('ltr' | 'rtl') | null; + format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | ''; + indent: number; + version: number; + }; + [k: string]: unknown; + } | null; + }; tab2?: { rt2?: { root: { - type: string + type: string; children: { - type: string - version: number - [k: string]: unknown - }[] - direction: ('ltr' | 'rtl') | null - format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | '' - indent: number - version: number - } - [k: string]: unknown - } | null - } - updatedAt?: string | null - createdAt?: string | null + type: string; + version: number; + [k: string]: unknown; + }[]; + direction: ('ltr' | 'rtl') | null; + format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | ''; + indent: number; + version: number; + }; + [k: string]: unknown; + } | null; + }; + updatedAt?: string | null; + createdAt?: string | null; } /** * This interface was referenced by `Config`'s JSON-Schema * via the `definition` "LexicalBlocksRadioButtonsBlock". */ export interface LexicalBlocksRadioButtonsBlock { - radioButtons?: ('option1' | 'option2' | 'option3') | null - id?: string | null - blockName?: string | null - blockType: 'radioButtons' + radioButtons?: ('option1' | 'option2' | 'option3') | null; + id?: string | null; + blockName?: string | null; + blockType: 'radioButtons'; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "auth". + */ +export interface Auth { + [k: string]: unknown; } + declare module 'payload' { - // @ts-ignore + // @ts-ignore export interface GeneratedTypes extends Config {} -} +} \ No newline at end of file diff --git a/test/helpers.ts b/test/helpers.ts index 268c00562d..b259b78520 100644 --- a/test/helpers.ts +++ b/test/helpers.ts @@ -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 { 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() } diff --git a/test/helpers/NextRESTClient.ts b/test/helpers/NextRESTClient.ts index 891ed5eb5c..c885e8b20c 100644 --- a/test/helpers/NextRESTClient.ts +++ b/test/helpers/NextRESTClient.ts @@ -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 } diff --git a/test/i18n/e2e.spec.ts b/test/i18n/e2e.spec.ts index 81023efaef..3f9bf8ec88 100644 --- a/test/i18n/e2e.spec.ts +++ b/test/i18n/e2e.spec.ts @@ -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 () => { diff --git a/test/live-preview/e2e.spec.ts b/test/live-preview/e2e.spec.ts index f6c738c28b..cec551bad5 100644 --- a/test/live-preview/e2e.spec.ts +++ b/test/live-preview/e2e.spec.ts @@ -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 () => { diff --git a/test/localization/e2e.spec.ts b/test/localization/e2e.spec.ts index c35339fa8b..530c703c8e 100644 --- a/test/localization/e2e.spec.ts +++ b/test/localization/e2e.spec.ts @@ -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', () => { diff --git a/test/package.json b/test/package.json index 5deb66bd2f..d5c623ffbd 100644 --- a/test/package.json +++ b/test/package.json @@ -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", diff --git a/test/plugin-cloud-storage/e2e.spec.ts b/test/plugin-cloud-storage/e2e.spec.ts index 2f9b692b7c..ecae889a06 100644 --- a/test/plugin-cloud-storage/e2e.spec.ts +++ b/test/plugin-cloud-storage/e2e.spec.ts @@ -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 () => { diff --git a/test/plugin-form-builder/e2e.spec.ts b/test/plugin-form-builder/e2e.spec.ts index 1af13e00c9..9b3ca7af12 100644 --- a/test/plugin-form-builder/e2e.spec.ts +++ b/test/plugin-form-builder/e2e.spec.ts @@ -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', () => { diff --git a/test/plugin-nested-docs/e2e.spec.ts b/test/plugin-nested-docs/e2e.spec.ts index 2047432f01..5ade24e7ad 100644 --- a/test/plugin-nested-docs/e2e.spec.ts +++ b/test/plugin-nested-docs/e2e.spec.ts @@ -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', () => { diff --git a/test/plugin-seo/e2e.spec.ts b/test/plugin-seo/e2e.spec.ts index be196cd453..86d688cc57 100644 --- a/test/plugin-seo/e2e.spec.ts +++ b/test/plugin-seo/e2e.spec.ts @@ -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', () => { diff --git a/test/uploads/e2e.spec.ts b/test/uploads/e2e.spec.ts index d83d1e95dc..a4fff3e1be 100644 --- a/test/uploads/e2e.spec.ts +++ b/test/uploads/e2e.spec.ts @@ -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 () => { diff --git a/test/versions/e2e.spec.ts b/test/versions/e2e.spec.ts index f444e352ac..d34fbab9ab 100644 --- a/test/versions/e2e.spec.ts +++ b/test/versions/e2e.spec.ts @@ -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) })