Compare commits

...

6 Commits

Author SHA1 Message Date
Jarrod Flesch
9a52c56acb fix: locale comparison not displaying values correctly 2024-07-29 15:15:50 -04:00
Jessica Chowdhury
ada9978a8c fix: page param not getting reset when applying filters (#7243)
Closes #7188

In the collection list view, after adding a filter, the page number
should be reset since the doc count will have changed.

---------

Co-authored-by: Jarrod Flesch <jarrodmflesch@gmail.com>
2024-07-29 13:25:43 -04:00
Jacob Fletcher
874279c530 fix(next): infinite loop when logging into root admin (#7412) 2024-07-29 12:57:57 -04:00
Paul
7ed6634bc5 fix: types for the 'validate' property across fields so internal validation functions can be reused (#7394)
Fixes the types for validate functions so that internal validation
functions can be re-used

Currently this has a type error
```ts
validate: (value, args) => {
  return text(value, args)
},
```
2024-07-29 12:36:28 -04:00
Michel v. Varendorff
09a0ee3ab9 fix: export default was not found in graphql (#6975) 2024-07-29 11:37:58 -04:00
Lynn Dylan Hurley
67acab2cd5 fix(searchPlugin): ensure search updates are unique to collection (#6363) 2024-07-29 11:33:59 -04:00
20 changed files with 185 additions and 67 deletions

View File

@@ -1,3 +1,3 @@
export { GraphQLJSON, GraphQLJSONObject } from '../packages/graphql-type-json/index.js'
export { buildPaginatedListType } from '../schema/buildPaginatedListType.js'
export { default as GraphQL } from 'graphql'
export * as GraphQL from 'graphql'

View File

@@ -7,7 +7,7 @@ import type {
import { notFound } from 'next/navigation.js'
import { isAdminAuthRoute, isAdminRoute } from './shared.js'
import { getRouteWithoutAdmin, isAdminAuthRoute, isAdminRoute } from './shared.js'
export const handleAdminPage = ({
adminRoute,
@@ -20,9 +20,9 @@ export const handleAdminPage = ({
permissions: Permissions
route: string
}) => {
if (isAdminRoute(route, adminRoute)) {
const baseAdminRoute = adminRoute && adminRoute !== '/' ? route.replace(adminRoute, '') : route
const routeSegments = baseAdminRoute.split('/').filter(Boolean)
if (isAdminRoute({ adminRoute, config, route })) {
const routeWithoutAdmin = getRouteWithoutAdmin({ adminRoute, route })
const routeSegments = routeWithoutAdmin.split('/').filter(Boolean)
const [entityType, entitySlug, createOrID] = routeSegments
const collectionSlug = entityType === 'collections' ? entitySlug : undefined
const globalSlug = entityType === 'globals' ? entitySlug : undefined
@@ -47,7 +47,7 @@ export const handleAdminPage = ({
}
}
if (!permissions.canAccessAdmin && !isAdminAuthRoute(config, route, adminRoute)) {
if (!permissions.canAccessAdmin && !isAdminAuthRoute({ adminRoute, config, route })) {
notFound()
}

View File

@@ -22,7 +22,7 @@ export const handleAuthRedirect = ({
routes: { admin: adminRoute },
} = config
if (!isAdminAuthRoute(config, route, adminRoute)) {
if (!isAdminAuthRoute({ adminRoute, config, route })) {
if (searchParams && 'redirect' in searchParams) delete searchParams.redirect
const redirectRoute = encodeURIComponent(
@@ -36,7 +36,7 @@ export const handleAuthRedirect = ({
const customLoginRoute =
typeof redirectUnauthenticatedUser === 'string' ? redirectUnauthenticatedUser : undefined
const loginRoute = isAdminRoute(route, adminRoute)
const loginRoute = isAdminRoute({ adminRoute, config, route })
? adminLoginRoute
: customLoginRoute || loginRouteFromConfig

View File

@@ -11,16 +11,42 @@ const authRouteKeys: (keyof SanitizedConfig['admin']['routes'])[] = [
'reset',
]
export const isAdminRoute = (route: string, adminRoute: string) => {
return route.startsWith(adminRoute)
export const isAdminRoute = ({
adminRoute,
config,
route,
}: {
adminRoute: string
config: SanitizedConfig
route: string
}): boolean => {
return route.startsWith(adminRoute) && !isAdminAuthRoute({ adminRoute, config, route })
}
export const isAdminAuthRoute = (config: SanitizedConfig, route: string, adminRoute: string) => {
export const isAdminAuthRoute = ({
adminRoute,
config,
route,
}: {
adminRoute: string
config: SanitizedConfig
route: string
}): boolean => {
const authRoutes = config.admin?.routes
? Object.entries(config.admin.routes)
.filter(([key]) => authRouteKeys.includes(key as keyof SanitizedConfig['admin']['routes']))
.map(([_, value]) => value)
: []
return authRoutes.some((r) => route.replace(adminRoute, '').startsWith(r))
return authRoutes.some((r) => getRouteWithoutAdmin({ adminRoute, route }).startsWith(r))
}
export const getRouteWithoutAdmin = ({
adminRoute,
route,
}: {
adminRoute: string
route: string
}): string => {
return adminRoute && adminRoute !== '/' ? route.replace(adminRoute, '') : route
}

View File

@@ -125,7 +125,7 @@ export const DefaultVersionView: React.FC<DefaultVersionsViewProps> = ({
value={compareValue}
versionID={versionID}
/>
{localization && (
{Boolean(localization) && (
<SelectLocales onChange={setLocales} options={localeOptions} value={locales} />
)}
</div>
@@ -138,7 +138,9 @@ export const DefaultVersionView: React.FC<DefaultVersionsViewProps> = ({
i18n={i18n}
locales={
locales
? locales.map(({ label }) => (typeof label === 'string' ? label : undefined))
? locales
.map(({ value }) => (typeof value === 'string' ? value : undefined))
.filter((label) => Boolean(label))
: []
}
version={

View File

@@ -266,11 +266,12 @@ export type NumberField = {
/** Set a value for the number field to increment / decrement using browser controls. */
step?: number
} & Admin
/** Maximum value accepted. Used in the default `validation` function. */
/** Maximum value accepted. Used in the default `validate` function. */
max?: number
/** Minimum value accepted. Used in the default `validation` function. */
/** Minimum value accepted. Used in the default `validate` function. */
min?: number
type: 'number'
validate?: Validate<number | number[], unknown, unknown, NumberField>
} & (
| {
/** Makes this field an ordered array of numbers instead of just a single number. */
@@ -306,6 +307,7 @@ export type TextField = {
maxLength?: number
minLength?: number
type: 'text'
validate?: Validate<string | string[], unknown, unknown, TextField>
} & (
| {
/** Makes this field an ordered array of strings instead of just a single string. */
@@ -338,6 +340,7 @@ export type EmailField = {
placeholder?: Record<string, string> | string
} & Admin
type: 'email'
validate?: Validate<string, unknown, unknown, EmailField>
} & FieldBase
export type TextareaField = {
@@ -355,6 +358,7 @@ export type TextareaField = {
maxLength?: number
minLength?: number
type: 'textarea'
validate?: Validate<string, unknown, unknown, TextareaField>
} & FieldBase
export type CheckboxField = {
@@ -367,6 +371,7 @@ export type CheckboxField = {
}
} & Admin
type: 'checkbox'
validate?: Validate<unknown, unknown, unknown, CheckboxField>
} & FieldBase
export type DateField = {
@@ -381,6 +386,7 @@ export type DateField = {
placeholder?: Record<string, string> | string
} & Admin
type: 'date'
validate?: Validate<unknown, unknown, unknown, DateField>
} & FieldBase
export type GroupField = {
@@ -396,7 +402,8 @@ export type GroupField = {
*/
interfaceName?: string
type: 'group'
} & Omit<FieldBase, 'required' | 'validation'>
validate?: Validate<unknown, unknown, unknown, GroupField>
} & Omit<FieldBase, 'required'>
export type RowAdmin = Omit<Admin, 'description'>
@@ -404,7 +411,7 @@ export type RowField = {
admin?: RowAdmin
fields: Field[]
type: 'row'
} & Omit<FieldBase, 'admin' | 'label' | 'name'>
} & Omit<FieldBase, 'admin' | 'label' | 'name' | 'validate'>
export type CollapsibleField = {
fields: Field[]
@@ -426,7 +433,7 @@ export type CollapsibleField = {
label: Required<FieldBase['label']>
}
) &
Omit<FieldBase, 'label' | 'name'>
Omit<FieldBase, 'label' | 'name' | 'validate'>
export type TabsAdmin = Omit<Admin, 'description'>
@@ -435,7 +442,7 @@ type TabBase = {
fields: Field[]
interfaceName?: string
saveToJWT?: boolean | string
} & Omit<FieldBase, 'required' | 'validation'>
} & Omit<FieldBase, 'required' | 'validate'>
export type NamedTab = {
/** Customize generated GraphQL and Typescript schema names.
@@ -521,6 +528,7 @@ export type UploadField = {
maxDepth?: number
relationTo: CollectionSlug
type: 'upload'
validate?: Validate<unknown, unknown, unknown, UploadField>
} & FieldBase
type CodeAdmin = {
@@ -537,6 +545,7 @@ export type CodeField = {
maxLength?: number
minLength?: number
type: 'code'
validate?: Validate<string, unknown, unknown, CodeField>
} & Omit<FieldBase, 'admin'>
type JSONAdmin = {
@@ -555,6 +564,7 @@ export type JSONField = {
uri: string
}
type: 'json'
validate?: Validate<Record<string, unknown>, unknown, unknown, JSONField>
} & Omit<FieldBase, 'admin'>
export type SelectField = {
@@ -577,6 +587,7 @@ export type SelectField = {
hasMany?: boolean
options: Option[]
type: 'select'
validate?: Validate<string, unknown, unknown, SelectField>
} & FieldBase
type SharedRelationshipProperties = {
@@ -589,6 +600,7 @@ type SharedRelationshipProperties = {
*/
maxDepth?: number
type: 'relationship'
validate?: Validate<unknown, unknown, unknown, SharedRelationshipProperties>
} & (
| {
hasMany: true
@@ -627,12 +639,14 @@ type RelationshipAdmin = {
}
isSortable?: boolean
} & Admin
export type PolymorphicRelationshipField = {
admin?: {
sortOptions?: { [collectionSlug: CollectionSlug]: string }
} & RelationshipAdmin
relationTo: CollectionSlug[]
} & SharedRelationshipProperties
export type SingleRelationshipField = {
admin?: {
sortOptions?: string
@@ -707,6 +721,7 @@ export type ArrayField = {
maxRows?: number
minRows?: number
type: 'array'
validate?: Validate<unknown[], unknown, unknown, ArrayField>
} & FieldBase
export type RadioField = {
@@ -727,6 +742,7 @@ export type RadioField = {
enumName?: DBIdentifierName
options: Option[]
type: 'radio'
validate?: Validate<string, unknown, unknown, RadioField>
} & FieldBase
export type Block = {
@@ -781,10 +797,12 @@ export type BlockField = {
maxRows?: number
minRows?: number
type: 'blocks'
validate?: Validate<string, unknown, unknown, BlockField>
} & FieldBase
export type PointField = {
type: 'point'
validate?: Validate<unknown, unknown, unknown, PointField>
} & FieldBase
export type Field =

View File

@@ -121,7 +121,7 @@ export const promise = async ({
}
// Validate
if (!skipValidationFromHere && field.validate) {
if (!skipValidationFromHere && 'validate' in field && field.validate) {
const valueToValidate = siblingData[field.name]
let jsonError: object

View File

@@ -85,6 +85,9 @@ export const syncWithSearch: SyncWithSearch = async (args) => {
'doc.value': {
equals: id,
},
'doc.relationTo': {
equals: collection,
},
},
})

View File

@@ -37,8 +37,8 @@ export const SortColumn: React.FC<SortColumnProps> = (props) => {
if (sort === desc) descClasses.push(`${baseClass}--active`)
const setSort = useCallback(
(newSort) => {
refineListData({
async (newSort: string) => {
await refineListData({
sort: newSort,
})
},
@@ -56,7 +56,7 @@ export const SortColumn: React.FC<SortColumnProps> = (props) => {
label,
})}
className={[...ascClasses, `${baseClass}__button`].filter(Boolean).join(' ')}
onClick={() => setSort(asc)}
onClick={() => void setSort(asc)}
type="button"
>
<ChevronIcon direction="up" />
@@ -67,7 +67,7 @@ export const SortColumn: React.FC<SortColumnProps> = (props) => {
label,
})}
className={[...descClasses, `${baseClass}__button`].filter(Boolean).join(' ')}
onClick={() => setSort(desc)}
onClick={() => void setSort(desc)}
type="button"
>
<ChevronIcon />

View File

@@ -143,8 +143,11 @@ export const WhereBuilder: React.FC<WhereBuilderProps> = (props) => {
React.useEffect(() => {
if (shouldUpdateQuery) {
handleWhereChange({ or: conditions })
setShouldUpdateQuery(false)
async function handleChange() {
await handleWhereChange({ or: conditions })
setShouldUpdateQuery(false)
}
void handleChange()
}
}, [conditions, handleWhereChange, shouldUpdateQuery])

View File

@@ -13,12 +13,19 @@ import { useSearchParams } from '../SearchParams/index.js'
export type ColumnPreferences = Pick<Column, 'accessor' | 'active'>[]
type Handlers = {
handlePageChange?: (page: number) => void
handlePerPageChange?: (limit: number) => void
handleSearchChange?: (search: string) => void
handleSortChange?: (sort: string) => void
handleWhereChange?: (where: Where) => void
type PropHandlers = {
handlePageChange?: (page: number) => Promise<void> | void
handlePerPageChange?: (limit: number) => Promise<void> | void
handleSearchChange?: (search: string) => Promise<void> | void
handleSortChange?: (sort: string) => Promise<void> | void
handleWhereChange?: (where: Where) => Promise<void> | void
}
type ContextHandlers = {
handlePageChange?: (page: number) => Promise<void>
handlePerPageChange?: (limit: number) => Promise<void>
handleSearchChange?: (search: string) => Promise<void>
handleSortChange?: (sort: string) => Promise<void>
handleWhereChange?: (where: Where) => Promise<void>
}
export type ListQueryProps = {
@@ -28,14 +35,14 @@ export type ListQueryProps = {
defaultSort?: string
modifySearchParams?: boolean
preferenceKey?: string
} & Handlers
} & PropHandlers
export type ListQueryContext = {
data: PaginatedDocs
defaultLimit?: number
defaultSort?: string
refineListData: (args: RefineOverrides) => void
} & Handlers
refineListData: (args: RefineOverrides) => Promise<void>
} & ContextHandlers
const Context = createContext({} as ListQueryContext)
@@ -71,6 +78,9 @@ export const ListQueryProvider: React.FC<ListQueryProps> = ({
async (query: RefineOverrides) => {
if (!modifySearchParams) return
let pageQuery = 'page' in query ? query.page : currentQuery?.page
if ('where' in query || 'search' in query) pageQuery = '1'
const updatedPreferences: Record<string, unknown> = {}
let updatePreferences = false
@@ -88,7 +98,7 @@ export const ListQueryProvider: React.FC<ListQueryProps> = ({
const params = {
limit: 'limit' in query ? query.limit : currentQuery?.limit,
page: 'page' in query ? query.page : currentQuery?.page,
page: pageQuery,
search: 'search' in query ? query.search : currentQuery?.search,
sort: 'sort' in query ? query.sort : currentQuery?.sort,
where: 'where' in query ? query.where : currentQuery?.where,
@@ -102,7 +112,7 @@ export const ListQueryProvider: React.FC<ListQueryProps> = ({
const handlePageChange = React.useCallback(
async (arg: number) => {
if (typeof handlePageChangeFromProps === 'function') {
handlePageChangeFromProps(arg)
await handlePageChangeFromProps(arg)
}
await refineListData({ page: String(arg) })
},
@@ -111,7 +121,7 @@ export const ListQueryProvider: React.FC<ListQueryProps> = ({
const handlePerPageChange = React.useCallback(
async (arg: number) => {
if (typeof handlePerPageChangeFromProps === 'function') {
handlePerPageChangeFromProps(arg)
await handlePerPageChangeFromProps(arg)
}
await refineListData({ limit: String(arg) })
},
@@ -120,7 +130,7 @@ export const ListQueryProvider: React.FC<ListQueryProps> = ({
const handleSearchChange = React.useCallback(
async (arg: string) => {
if (typeof handleSearchChangeFromProps === 'function') {
handleSearchChangeFromProps(arg)
await handleSearchChangeFromProps(arg)
}
await refineListData({ search: arg })
},
@@ -129,7 +139,7 @@ export const ListQueryProvider: React.FC<ListQueryProps> = ({
const handleSortChange = React.useCallback(
async (arg: string) => {
if (typeof handleSortChangeFromProps === 'function') {
handleSortChangeFromProps(arg)
await handleSortChangeFromProps(arg)
}
await refineListData({ sort: arg })
},
@@ -138,7 +148,7 @@ export const ListQueryProvider: React.FC<ListQueryProps> = ({
const handleWhereChange = React.useCallback(
async (arg: Where) => {
if (typeof handleWhereChangeFromProps === 'function') {
handleWhereChangeFromProps(arg)
await handleWhereChangeFromProps(arg)
}
await refineListData({ where: arg })
},

View File

@@ -18,7 +18,7 @@ import {
closeNav,
ensureCompilationIsDone,
exactText,
getAdminRoutes,
getRoutes,
initPageConsoleErrorCatch,
login,
openDocControls,
@@ -99,7 +99,7 @@ describe('access control', () => {
routes: { logout: logoutRoute },
},
routes: { admin: adminRoute },
} = getAdminRoutes({})
} = getRoutes({})
logoutURL = `${serverURL}${adminRoute}${logoutRoute}`
})

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@@ -12,6 +12,13 @@ const dirname = path.dirname(filename)
export default buildConfigWithDefaults({
collections: [PostsCollection],
admin: {
autoLogin: {
email: devUser.email,
password: devUser.password,
prefillOnly: true,
},
},
cors: ['http://localhost:3000', 'http://localhost:3001'],
globals: [MenuGlobal],
routes: {

View File

@@ -5,7 +5,7 @@ import * as path from 'path'
import { adminRoute } from 'shared.js'
import { fileURLToPath } from 'url'
import { ensureCompilationIsDone, initPageConsoleErrorCatch } from '../helpers.js'
import { ensureCompilationIsDone, initPageConsoleErrorCatch, login } from '../helpers.js'
import { AdminUrlUtil } from '../helpers/adminUrlUtil.js'
import { initPayloadE2ENoConfig } from '../helpers/initPayloadE2ENoConfig.js'
import { TEST_TIMEOUT_LONG } from '../playwright.config.js'
@@ -29,6 +29,8 @@ test.describe('Admin Panel (Root)', () => {
page = await context.newPage()
initPageConsoleErrorCatch(page)
await login({ page, serverURL, customRoutes: { admin: adminRoute } })
await ensureCompilationIsDone({
customRoutes: {
admin: adminRoute,

View File

@@ -10,7 +10,7 @@ import {
checkPageTitle,
ensureCompilationIsDone,
exactText,
getAdminRoutes,
getRoutes,
initPageConsoleErrorCatch,
openDocControls,
openNav,
@@ -76,7 +76,7 @@ describe('admin1', () => {
let customFieldsURL: AdminUrlUtil
let disableDuplicateURL: AdminUrlUtil
let serverURL: string
let adminRoutes: ReturnType<typeof getAdminRoutes>
let adminRoutes: ReturnType<typeof getRoutes>
let loginURL: string
beforeAll(async ({ browser }, testInfo) => {
@@ -106,7 +106,7 @@ describe('admin1', () => {
await ensureCompilationIsDone({ customAdminRoutes, page, serverURL })
adminRoutes = getAdminRoutes({ customAdminRoutes })
adminRoutes = getRoutes({ customAdminRoutes })
loginURL = `${serverURL}${adminRoutes.routes.admin}${adminRoutes.admin.routes.login}`
})

View File

@@ -10,7 +10,7 @@ import type { Config, Geo, Post } from '../../payload-types.js'
import {
ensureCompilationIsDone,
exactText,
getAdminRoutes,
getRoutes,
initPageConsoleErrorCatch,
openDocDrawer,
openNav,
@@ -44,7 +44,7 @@ describe('admin2', () => {
let postsUrl: AdminUrlUtil
let serverURL: string
let adminRoutes: ReturnType<typeof getAdminRoutes>
let adminRoutes: ReturnType<typeof getRoutes>
beforeAll(async ({ browser }, testInfo) => {
const prebuild = Boolean(process.env.CI)
@@ -69,7 +69,7 @@ describe('admin2', () => {
await ensureCompilationIsDone({ customAdminRoutes, page, serverURL })
adminRoutes = getAdminRoutes({ customAdminRoutes })
adminRoutes = getRoutes({ customAdminRoutes })
})
beforeEach(async () => {
await reInitializeDB({
@@ -421,6 +421,42 @@ describe('admin2', () => {
await expect(page.getByPlaceholder('Enter a value')).toHaveValue('[object Object]')
await expect(page.locator(tableRowLocator)).toHaveCount(1)
})
test('should reset page when filters are applied', async () => {
await deleteAllPosts()
await mapAsync([...Array(6)], async () => {
await createPost()
})
await page.reload()
await mapAsync([...Array(6)], async () => {
await createPost({ title: 'test' })
})
await page.reload()
const pageInfo = page.locator('.collection-list__page-info')
const perPage = page.locator('.per-page')
const tableItems = page.locator(tableRowLocator)
await expect(tableItems).toHaveCount(10)
await expect(pageInfo).toHaveText('1-10 of 12')
await expect(perPage).toContainText('Per Page: 10')
// go to page 2
await page.goto(`${postsUrl.list}?limit=10&page=2`)
// add filter
await page.locator('.list-controls__toggle-where').click()
await page.locator('.where-builder__add-first-filter').click()
await page.locator('.condition__field .rs__control').click()
const options = page.locator('.rs__option')
await options.locator('text=Tab 1 > Title').click()
await page.locator('.condition__operator .rs__control').click()
await options.locator('text=equals').click()
await page.locator('.condition__value input').fill('test')
// expect to be on page 1
await expect(pageInfo).toHaveText('1-6 of 6')
})
})
describe('table columns', () => {

View File

@@ -13,7 +13,7 @@ import type { Config } from './payload-types.js'
import {
ensureCompilationIsDone,
getAdminRoutes,
getRoutes,
initPageConsoleErrorCatch,
saveDocAndAssert,
} from '../helpers.js'
@@ -49,7 +49,7 @@ const createFirstUser = async ({
routes: { createFirstUser: createFirstUserRoute },
},
routes: { admin: adminRoute },
} = getAdminRoutes({
} = getRoutes({
customAdminRoutes,
customRoutes,
})

View File

@@ -1,6 +1,7 @@
import type { BrowserContext, ChromiumBrowserContext, Locator, Page } from '@playwright/test'
import type { Config } from 'payload'
import { formatAdminURL } from '@payloadcms/ui/shared'
import { expect } from '@playwright/test'
import { defaults } from 'payload'
import { wait } from 'payload/shared'
@@ -65,7 +66,7 @@ export async function ensureCompilationIsDone({
}): Promise<void> {
const {
routes: { admin: adminRoute },
} = getAdminRoutes({ customAdminRoutes, customRoutes })
} = getRoutes({ customAdminRoutes, customRoutes })
const adminURL = `${serverURL}${adminRoute}`
@@ -114,7 +115,7 @@ export async function firstRegister(args: FirstRegisterArgs): Promise<void> {
const {
routes: { admin: adminRoute },
} = getAdminRoutes({ customAdminRoutes, customRoutes })
} = getRoutes({ customAdminRoutes, customRoutes })
await page.goto(`${serverURL}${adminRoute}`)
await page.fill('#field-email', devUser.email)
@@ -130,27 +131,37 @@ export async function login(args: LoginArgs): Promise<void> {
const {
admin: {
routes: { createFirstUser: createFirstUserRoute, login: loginRoute },
routes: { createFirstUser, login: incomingLoginRoute },
},
routes: { admin: adminRoute },
} = getAdminRoutes({ customAdminRoutes, customRoutes })
routes: { admin: incomingAdminRoute },
} = getRoutes({ customAdminRoutes, customRoutes })
await page.goto(`${serverURL}${adminRoute}${loginRoute}`)
await page.waitForURL(`${serverURL}${adminRoute}${loginRoute}`)
const adminRoute = formatAdminURL({ serverURL, adminRoute: incomingAdminRoute, path: '' })
const loginRoute = formatAdminURL({
serverURL,
adminRoute: incomingAdminRoute,
path: incomingLoginRoute,
})
const createFirstUserRoute = formatAdminURL({
serverURL,
adminRoute: incomingAdminRoute,
path: createFirstUser,
})
await page.goto(loginRoute)
await page.waitForURL(loginRoute)
await wait(500)
await page.fill('#field-email', data.email)
await page.fill('#field-password', data.password)
await wait(500)
await page.click('[type=submit]')
await page.waitForURL(`${serverURL}${adminRoute}`)
await page.waitForURL(adminRoute)
await expect(() => expect(page.url()).not.toContain(`${adminRoute}${loginRoute}`)).toPass({
await expect(() => expect(page.url()).not.toContain(loginRoute)).toPass({
timeout: POLL_TOPASS_TIMEOUT,
})
await expect(() =>
expect(page.url()).not.toContain(`${adminRoute}${createFirstUserRoute}`),
).toPass({
await expect(() => expect(page.url()).not.toContain(createFirstUserRoute)).toPass({
timeout: POLL_TOPASS_TIMEOUT,
})
}
@@ -328,7 +339,7 @@ export function describeIfInCIOrHasLocalstack(): jest.Describe {
type AdminRoutes = Config['admin']['routes']
export function getAdminRoutes({
export function getRoutes({
customAdminRoutes,
customRoutes,
}: {

View File

@@ -37,7 +37,7 @@
],
"paths": {
"@payload-config": [
"./test/admin/config.ts"
"./test/_community/config.ts"
],
"@payloadcms/live-preview": [
"./packages/live-preview/src"