Compare commits
9 Commits
v3.0.0-bet
...
v3.0.0-bet
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8c39950ea3 | ||
|
|
6d642fe9b9 | ||
|
|
f175a741bc | ||
|
|
3290376f80 | ||
|
|
2b5c1ba99a | ||
|
|
bcb3f08386 | ||
|
|
b729b9bebd | ||
|
|
26ee91eb48 | ||
|
|
43a17f67a0 |
42
.github/workflows/main.yml
vendored
42
.github/workflows/main.yml
vendored
@@ -13,6 +13,8 @@ concurrency:
|
||||
env:
|
||||
NODE_VERSION: 18.20.2
|
||||
PNPM_VERSION: 8.15.7
|
||||
DO_NOT_TRACK: 1 # Disable Turbopack telemetry
|
||||
NEXT_TELEMETRY_DISABLED: 1 # Disable Next telemetry
|
||||
|
||||
jobs:
|
||||
changes:
|
||||
@@ -89,6 +91,8 @@ jobs:
|
||||
|
||||
- run: pnpm install
|
||||
- run: pnpm run build:all
|
||||
env:
|
||||
DO_NOT_TRACK: 1 # Disable Turbopack telemetry
|
||||
|
||||
- name: Cache build
|
||||
uses: actions/cache@v4
|
||||
@@ -253,7 +257,8 @@ jobs:
|
||||
- plugin-seo
|
||||
- versions
|
||||
- uploads
|
||||
|
||||
env:
|
||||
SUITE_NAME: ${{ matrix.suite }}
|
||||
steps:
|
||||
# https://github.com/actions/virtual-environments/issues/1187
|
||||
- name: tune linux network
|
||||
@@ -281,11 +286,33 @@ jobs:
|
||||
run: pnpm docker:start
|
||||
if: ${{ matrix.suite == 'plugin-cloud-storage' }}
|
||||
|
||||
- name: Install Playwright
|
||||
run: pnpm exec playwright install --with-deps
|
||||
- name: Store Playwright's Version
|
||||
run: |
|
||||
# Extract the version number using a more targeted regex pattern with awk
|
||||
PLAYWRIGHT_VERSION=$(pnpm ls @playwright/test --depth=0 | awk '/@playwright\/test/ {print $2}')
|
||||
echo "Playwright's Version: $PLAYWRIGHT_VERSION"
|
||||
echo "PLAYWRIGHT_VERSION=$PLAYWRIGHT_VERSION" >> $GITHUB_ENV
|
||||
|
||||
- name: Cache Playwright Browsers for Playwright's Version
|
||||
id: cache-playwright-browsers
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ~/.cache/ms-playwright
|
||||
key: playwright-browsers-${{ env.PLAYWRIGHT_VERSION }}
|
||||
|
||||
- name: Setup Playwright - Browsers and Dependencies
|
||||
if: steps.cache-playwright-browsers.outputs.cache-hit != 'true'
|
||||
run: pnpm exec playwright install --with-deps chromium
|
||||
|
||||
- name: Setup Playwright - Dependencies-only
|
||||
if: steps.cache-playwright-browsers.outputs.cache-hit == 'true'
|
||||
run: pnpm exec playwright install-deps chromium
|
||||
|
||||
- name: E2E Tests
|
||||
run: pnpm test:e2e ${{ matrix.suite }}
|
||||
run: PLAYWRIGHT_JSON_OUTPUT_NAME=results_${{ matrix.suite }}.json pnpm test:e2e ${{ matrix.suite }}
|
||||
env:
|
||||
PLAYWRIGHT_JSON_OUTPUT_NAME: results_${{ matrix.suite }}.json
|
||||
NEXT_TELEMETRY_DISABLED: 1
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
if: always()
|
||||
@@ -295,6 +322,13 @@ jobs:
|
||||
if-no-files-found: ignore
|
||||
retention-days: 1
|
||||
|
||||
# Disabled until this is fixed: https://github.com/daun/playwright-report-summary/issues/156
|
||||
# - uses: daun/playwright-report-summary@v3
|
||||
# with:
|
||||
# report-file: results_${{ matrix.suite }}.json
|
||||
# report-tag: ${{ matrix.suite }}
|
||||
# job-summary: true
|
||||
|
||||
app-build-with-packed:
|
||||
runs-on: ubuntu-latest
|
||||
needs: build
|
||||
|
||||
@@ -49,7 +49,8 @@ export default buildConfig({
|
||||
{
|
||||
label: 'Arabic',
|
||||
code: 'ar',
|
||||
// opt-in to setting default text-alignment on Input fields to rtl (right-to-left) when current locale is rtl
|
||||
// opt-in to setting default text-alignment on Input fields to rtl (right-to-left)
|
||||
// when current locale is rtl
|
||||
rtl: true,
|
||||
},
|
||||
],
|
||||
@@ -134,13 +135,9 @@ to support localization, you need to specify each field that you would like to l
|
||||
```js
|
||||
{
|
||||
name: 'title',
|
||||
type
|
||||
:
|
||||
'text',
|
||||
// highlight-start
|
||||
localized
|
||||
:
|
||||
true,
|
||||
type: 'text',
|
||||
// highlight-start
|
||||
localized: true,
|
||||
// highlight-end
|
||||
}
|
||||
```
|
||||
|
||||
@@ -20,7 +20,8 @@ The initial request made to Payload will begin a new transaction and attach it t
|
||||
|
||||
```ts
|
||||
const afterChange: CollectionAfterChangeHook = async ({ req }) => {
|
||||
// because req.transactionID is assigned from Payload and passed through, my-slug will only persist if the entire request is successful
|
||||
// because req.transactionID is assigned from Payload and passed through,
|
||||
// my-slug will only persist if the entire request is successful
|
||||
await req.payload.create({
|
||||
req,
|
||||
collection: 'my-slug',
|
||||
|
||||
@@ -196,7 +196,8 @@ const Pages: CollectionConfig = {
|
||||
editor: lexicalEditor({
|
||||
features: ({ defaultFeatures }) => [
|
||||
...defaultFeatures,
|
||||
// The HTMLConverter Feature is the feature which manages the HTML serializers. If you do not pass any arguments to it, it will use the default serializers.
|
||||
// The HTMLConverter Feature is the feature which manages the HTML serializers.
|
||||
// If you do not pass any arguments to it, it will use the default serializers.
|
||||
HTMLConverterFeature({}),
|
||||
],
|
||||
}),
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "payload-monorepo",
|
||||
"version": "3.0.0-beta.21",
|
||||
"version": "3.0.0-beta.22",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "create-payload-app",
|
||||
"version": "3.0.0-beta.21",
|
||||
"version": "3.0.0-beta.22",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/db-mongodb",
|
||||
"version": "3.0.0-beta.21",
|
||||
"version": "3.0.0-beta.22",
|
||||
"description": "The officially supported MongoDB database adapter for Payload",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/db-postgres",
|
||||
"version": "3.0.0-beta.21",
|
||||
"version": "3.0.0-beta.22",
|
||||
"description": "The officially supported Postgres database adapter for Payload",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/email-nodemailer",
|
||||
"version": "3.0.0-beta.21",
|
||||
"version": "3.0.0-beta.22",
|
||||
"description": "Payload Nodemailer Email Adapter",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/email-resend",
|
||||
"version": "3.0.0-beta.21",
|
||||
"version": "3.0.0-beta.22",
|
||||
"description": "Payload Resend Email Adapter",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/graphql",
|
||||
"version": "3.0.0-beta.21",
|
||||
"version": "3.0.0-beta.22",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/next",
|
||||
"version": "3.0.0-beta.21",
|
||||
"version": "3.0.0-beta.22",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
||||
@@ -5,3 +5,4 @@ export { createPayloadRequest } from '../utilities/createPayloadRequest.js'
|
||||
export { getNextRequestI18n } from '../utilities/getNextRequestI18n.js'
|
||||
export { getPayloadHMR, reload } from '../utilities/getPayloadHMR.js'
|
||||
export { headersWithCors } from '../utilities/headersWithCors.js'
|
||||
export { initPage } from '../utilities/initPage.js'
|
||||
|
||||
@@ -99,6 +99,7 @@ export const initPage = async ({
|
||||
const globalSlug = entityType === 'globals' ? entitySlug : undefined
|
||||
const docID = collectionSlug && createOrID !== 'create' ? createOrID : undefined
|
||||
|
||||
const isAdminRoute = route.startsWith(adminRoute)
|
||||
const isAuthRoute = authRoutes.some((r) => r === route.replace(adminRoute, ''))
|
||||
|
||||
if (redirectUnauthenticatedUser && !user && !isAuthRoute) {
|
||||
@@ -111,7 +112,7 @@ export const initPage = async ({
|
||||
redirect(`${routes.admin}/login?redirect=${route + stringifiedSearchParams}`)
|
||||
}
|
||||
|
||||
if (!permissions.canAccessAdmin && !isAuthRoute) {
|
||||
if (!permissions.canAccessAdmin && isAdminRoute && !isAuthRoute) {
|
||||
notFound()
|
||||
}
|
||||
|
||||
|
||||
@@ -46,10 +46,13 @@ export const NotFoundPage = async ({
|
||||
[key: string]: string | string[]
|
||||
}
|
||||
}) => {
|
||||
const config = await configPromise
|
||||
const { routes: { admin: adminRoute } = {} } = config
|
||||
|
||||
const initPageResult = await initPage({
|
||||
config: configPromise,
|
||||
config,
|
||||
redirectUnauthenticatedUser: true,
|
||||
route: '/not-found',
|
||||
route: `${adminRoute}/not-found`,
|
||||
searchParams,
|
||||
})
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "payload",
|
||||
"version": "3.0.0-beta.21",
|
||||
"version": "3.0.0-beta.22",
|
||||
"description": "Node, React, Headless CMS and Application Framework built on Next.js",
|
||||
"keywords": [
|
||||
"admin panel",
|
||||
|
||||
@@ -141,6 +141,10 @@ export const loginOperation = async <TSlug extends keyof GeneratedTypes['collect
|
||||
user,
|
||||
})
|
||||
|
||||
// /////////////////////////////////////
|
||||
// beforeLogin - Collection
|
||||
// /////////////////////////////////////
|
||||
|
||||
await collectionConfig.hooks.beforeLogin.reduce(async (priorHook, hook) => {
|
||||
await priorHook
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/plugin-cloud-storage",
|
||||
"version": "3.0.0-beta.21",
|
||||
"version": "3.0.0-beta.22",
|
||||
"description": "The official cloud storage plugin for Payload CMS",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/plugin-cloud",
|
||||
"version": "3.0.0-beta.21",
|
||||
"version": "3.0.0-beta.22",
|
||||
"description": "The official Payload Cloud plugin",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/plugin-form-builder",
|
||||
"version": "3.0.0-beta.21",
|
||||
"version": "3.0.0-beta.22",
|
||||
"description": "Form builder plugin for Payload CMS",
|
||||
"keywords": [
|
||||
"payload",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/plugin-nested-docs",
|
||||
"version": "3.0.0-beta.21",
|
||||
"version": "3.0.0-beta.22",
|
||||
"description": "The official Nested Docs plugin for Payload",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/plugin-redirects",
|
||||
"version": "3.0.0-beta.21",
|
||||
"version": "3.0.0-beta.22",
|
||||
"description": "Redirects plugin for Payload",
|
||||
"keywords": [
|
||||
"payload",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/plugin-search",
|
||||
"version": "3.0.0-beta.21",
|
||||
"version": "3.0.0-beta.22",
|
||||
"description": "Search plugin for Payload",
|
||||
"keywords": [
|
||||
"payload",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/plugin-seo",
|
||||
"version": "3.0.0-beta.21",
|
||||
"version": "3.0.0-beta.22",
|
||||
"description": "SEO plugin for Payload",
|
||||
"keywords": [
|
||||
"payload",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/richtext-lexical",
|
||||
"version": "3.0.0-beta.21",
|
||||
"version": "3.0.0-beta.22",
|
||||
"description": "The officially supported Lexical richtext adapter for Payload",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
|
||||
@@ -346,7 +346,10 @@ export { StrikethroughFeature } from './field/features/format/strikethrough/feat
|
||||
export { SubscriptFeature } from './field/features/format/subscript/feature.server.js'
|
||||
export { SuperscriptFeature } from './field/features/format/superscript/feature.server.js'
|
||||
export { UnderlineFeature } from './field/features/format/underline/feature.server.js'
|
||||
export { HeadingFeature } from './field/features/heading/feature.server.js'
|
||||
export {
|
||||
HeadingFeature,
|
||||
type HeadingFeatureProps,
|
||||
} from './field/features/heading/feature.server.js'
|
||||
|
||||
export { HorizontalRuleFeature } from './field/features/horizontalrule/feature.server.js'
|
||||
export { IndentFeature } from './field/features/indent/feature.server.js'
|
||||
@@ -395,7 +398,10 @@ export type {
|
||||
} from './field/features/migrations/slateToLexical/converter/types.js'
|
||||
export { SlateToLexicalFeature } from './field/features/migrations/slateToLexical/feature.server.js'
|
||||
export { ParagraphFeature } from './field/features/paragraph/feature.server.js'
|
||||
export { RelationshipFeature } from './field/features/relationship/feature.server.js'
|
||||
export {
|
||||
RelationshipFeature,
|
||||
type RelationshipFeatureProps,
|
||||
} from './field/features/relationship/feature.server.js'
|
||||
export {
|
||||
$createRelationshipNode,
|
||||
$isRelationshipNode,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/richtext-slate",
|
||||
"version": "3.0.0-beta.21",
|
||||
"version": "3.0.0-beta.22",
|
||||
"description": "The officially supported Slate richtext adapter for Payload",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/storage-azure",
|
||||
"version": "3.0.0-beta.21",
|
||||
"version": "3.0.0-beta.22",
|
||||
"description": "Payload storage adapter for Azure Blob Storage",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/storage-gcs",
|
||||
"version": "3.0.0-beta.21",
|
||||
"version": "3.0.0-beta.22",
|
||||
"description": "Payload storage adapter for Google Cloud Storage",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/storage-s3",
|
||||
"version": "3.0.0-beta.21",
|
||||
"version": "3.0.0-beta.22",
|
||||
"description": "Payload storage adapter for Amazon S3",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/storage-vercel-blob",
|
||||
"version": "3.0.0-beta.21",
|
||||
"version": "3.0.0-beta.22",
|
||||
"description": "Payload storage adapter for Vercel Blob Storage",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/translations",
|
||||
"version": "3.0.0-beta.21",
|
||||
"version": "3.0.0-beta.22",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/ui",
|
||||
"version": "3.0.0-beta.21",
|
||||
"version": "3.0.0-beta.22",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */
|
||||
import configPromise from '@payload-config'
|
||||
import '@payloadcms/next/css'
|
||||
import { RootLayout } from '@payloadcms/next/layouts'
|
||||
/* DO NOT MODIFY IT BECAUSE IT COULD BE REWRITTEN AT ANY TIME. */
|
||||
import React from 'react'
|
||||
|
||||
@@ -7,6 +7,7 @@ import { fileURLToPath } from 'url'
|
||||
import { ensureAutoLoginAndCompilationIsDone, initPageConsoleErrorCatch } from '../helpers.js'
|
||||
import { AdminUrlUtil } from '../helpers/adminUrlUtil.js'
|
||||
import { initPayloadE2ENoConfig } from '../helpers/initPayloadE2ENoConfig.js'
|
||||
import { TEST_TIMEOUT, TEST_TIMEOUT_LONG } from '../playwright.config.js'
|
||||
|
||||
const filename = fileURLToPath(import.meta.url)
|
||||
const dirname = path.dirname(filename)
|
||||
@@ -15,7 +16,9 @@ test.describe('Admin Panel', () => {
|
||||
let page: Page
|
||||
let url: AdminUrlUtil
|
||||
|
||||
test.beforeAll(async ({ browser }) => {
|
||||
test.beforeAll(async ({ browser }, testInfo) => {
|
||||
testInfo.setTimeout(TEST_TIMEOUT_LONG)
|
||||
|
||||
const { payload, serverURL } = await initPayloadE2ENoConfig({ dirname })
|
||||
url = new AdminUrlUtil(serverURL, 'posts')
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { Page } from '@playwright/test'
|
||||
import type { BrowserContext, Page } from '@playwright/test'
|
||||
import type { TypeWithID } from 'payload/types'
|
||||
|
||||
import { expect, test } from '@playwright/test'
|
||||
@@ -22,7 +22,7 @@ import {
|
||||
} from '../helpers.js'
|
||||
import { AdminUrlUtil } from '../helpers/adminUrlUtil.js'
|
||||
import { initPayloadE2ENoConfig } from '../helpers/initPayloadE2ENoConfig.js'
|
||||
import { POLL_TOPASS_TIMEOUT } from '../playwright.config.js'
|
||||
import { POLL_TOPASS_TIMEOUT, TEST_TIMEOUT, TEST_TIMEOUT_LONG } from '../playwright.config.js'
|
||||
import {
|
||||
docLevelAccessSlug,
|
||||
noAdminAccessEmail,
|
||||
@@ -59,7 +59,8 @@ describe('access control', () => {
|
||||
let serverURL: string
|
||||
let context: BrowserContext
|
||||
|
||||
beforeAll(async ({ browser }) => {
|
||||
beforeAll(async ({ browser }, testInfo) => {
|
||||
testInfo.setTimeout(TEST_TIMEOUT_LONG)
|
||||
;({ payload, serverURL } = await initPayloadE2ENoConfig<Config>({ dirname }))
|
||||
|
||||
url = new AdminUrlUtil(serverURL, slug)
|
||||
@@ -73,6 +74,7 @@ describe('access control', () => {
|
||||
initPageConsoleErrorCatch(page)
|
||||
|
||||
await login({ page, serverURL })
|
||||
await ensureAutoLoginAndCompilationIsDone({ page, serverURL })
|
||||
})
|
||||
|
||||
test('field without read access should not show', async () => {
|
||||
|
||||
@@ -61,7 +61,7 @@ import { fileURLToPath } from 'url'
|
||||
import type { PayloadTestSDK } from '../helpers/sdk/index.js'
|
||||
|
||||
import { reInitializeDB } from '../helpers/reInitializeDB.js'
|
||||
import { POLL_TOPASS_TIMEOUT } from '../playwright.config.js'
|
||||
import { POLL_TOPASS_TIMEOUT, TEST_TIMEOUT, TEST_TIMEOUT_LONG } from '../playwright.config.js'
|
||||
const filename = fileURLToPath(import.meta.url)
|
||||
const dirname = path.dirname(filename)
|
||||
|
||||
@@ -76,7 +76,7 @@ describe('admin', () => {
|
||||
beforeAll(async ({ browser }, testInfo) => {
|
||||
const prebuild = Boolean(process.env.CI)
|
||||
|
||||
if (prebuild) testInfo.setTimeout(testInfo.timeout * 3)
|
||||
testInfo.setTimeout(TEST_TIMEOUT_LONG)
|
||||
|
||||
process.env.SEED_IN_CONFIG_ONINIT = 'false' // Makes it so the payload config onInit seed is not run. Otherwise, the seed would be run unnecessarily twice for the initial test run - once for beforeEach and once for onInit
|
||||
;({ payload, serverURL } = await initPayloadE2ENoConfig<Config>({
|
||||
@@ -91,6 +91,11 @@ describe('admin', () => {
|
||||
const context = await browser.newContext()
|
||||
page = await context.newPage()
|
||||
initPageConsoleErrorCatch(page)
|
||||
await reInitializeDB({
|
||||
serverURL,
|
||||
snapshotKey: 'adminTests',
|
||||
})
|
||||
await ensureAutoLoginAndCompilationIsDone({ page, serverURL })
|
||||
})
|
||||
beforeEach(async () => {
|
||||
await reInitializeDB({
|
||||
|
||||
@@ -10,10 +10,14 @@ import { v4 as uuid } from 'uuid'
|
||||
import type { PayloadTestSDK } from '../helpers/sdk/index.js'
|
||||
import type { Config } from './payload-types.js'
|
||||
|
||||
import { initPageConsoleErrorCatch, saveDocAndAssert } from '../helpers.js'
|
||||
import {
|
||||
ensureAutoLoginAndCompilationIsDone,
|
||||
initPageConsoleErrorCatch,
|
||||
saveDocAndAssert,
|
||||
} from '../helpers.js'
|
||||
import { AdminUrlUtil } from '../helpers/adminUrlUtil.js'
|
||||
import { initPayloadE2ENoConfig } from '../helpers/initPayloadE2ENoConfig.js'
|
||||
import { POLL_TOPASS_TIMEOUT } from '../playwright.config.js'
|
||||
import { POLL_TOPASS_TIMEOUT, TEST_TIMEOUT_LONG } from '../playwright.config.js'
|
||||
import { apiKeysSlug, slug } from './shared.js'
|
||||
|
||||
const filename = fileURLToPath(import.meta.url)
|
||||
@@ -52,7 +56,8 @@ describe('auth', () => {
|
||||
// Allows for testing create-first-user
|
||||
process.env.SKIP_ON_INIT = 'true'
|
||||
|
||||
beforeAll(async ({ browser }) => {
|
||||
beforeAll(async ({ browser }, testInfo) => {
|
||||
testInfo.setTimeout(TEST_TIMEOUT_LONG)
|
||||
;({ payload, serverURL } = await initPayloadE2ENoConfig<Config>({ dirname }))
|
||||
apiURL = `${serverURL}/api`
|
||||
url = new AdminUrlUtil(serverURL, slug)
|
||||
@@ -78,6 +83,7 @@ describe('auth', () => {
|
||||
enableAPIKey: true,
|
||||
},
|
||||
})
|
||||
await ensureAutoLoginAndCompilationIsDone({ page, serverURL })
|
||||
})
|
||||
|
||||
describe('authenticated users', () => {
|
||||
|
||||
@@ -6,6 +6,7 @@ import { fileURLToPath } from 'url'
|
||||
|
||||
import { ensureAutoLoginAndCompilationIsDone, initPageConsoleErrorCatch } from '../helpers.js'
|
||||
import { initPayloadE2ENoConfig } from '../helpers/initPayloadE2ENoConfig.js'
|
||||
import { TEST_TIMEOUT_LONG } from '../playwright.config.js'
|
||||
|
||||
const { beforeAll, describe } = test
|
||||
const filename = fileURLToPath(import.meta.url)
|
||||
@@ -15,7 +16,8 @@ describe('field error states', () => {
|
||||
let serverURL: string
|
||||
let page: Page
|
||||
|
||||
beforeAll(async ({ browser }) => {
|
||||
beforeAll(async ({ browser }, testInfo) => {
|
||||
testInfo.setTimeout(TEST_TIMEOUT_LONG)
|
||||
;({ serverURL } = await initPayloadE2ENoConfig({ dirname }))
|
||||
const context = await browser.newContext()
|
||||
page = await context.newPage()
|
||||
|
||||
@@ -17,15 +17,16 @@ import type {
|
||||
} from './payload-types.js'
|
||||
|
||||
import {
|
||||
delayNetwork,
|
||||
ensureAutoLoginAndCompilationIsDone,
|
||||
initPageConsoleErrorCatch,
|
||||
openDocControls,
|
||||
openDocDrawer,
|
||||
saveDocAndAssert,
|
||||
throttleTest,
|
||||
} from '../helpers.js'
|
||||
import { AdminUrlUtil } from '../helpers/adminUrlUtil.js'
|
||||
import { initPayloadE2ENoConfig } from '../helpers/initPayloadE2ENoConfig.js'
|
||||
import { TEST_TIMEOUT_LONG } from '../playwright.config.js'
|
||||
import {
|
||||
relationFalseFilterOptionSlug,
|
||||
relationOneSlug,
|
||||
@@ -56,7 +57,8 @@ describe('fields - relationship', () => {
|
||||
let relationWithTitle: RelationWithTitle
|
||||
let serverURL: string
|
||||
|
||||
beforeAll(async ({ browser }) => {
|
||||
beforeAll(async ({ browser }, testInfo) => {
|
||||
testInfo.setTimeout(TEST_TIMEOUT_LONG)
|
||||
;({ payload, serverURL } = await initPayloadE2ENoConfig<Config>({ dirname }))
|
||||
|
||||
url = new AdminUrlUtil(serverURL, slug)
|
||||
@@ -65,6 +67,7 @@ describe('fields - relationship', () => {
|
||||
page = await context.newPage()
|
||||
|
||||
initPageConsoleErrorCatch(page)
|
||||
await ensureAutoLoginAndCompilationIsDone({ page, serverURL })
|
||||
})
|
||||
|
||||
beforeEach(async () => {
|
||||
@@ -374,6 +377,7 @@ describe('fields - relationship', () => {
|
||||
await expect(options).not.toContainText('whatever')
|
||||
})
|
||||
|
||||
// TODO: Flaky test in CI - fix.
|
||||
test('should show a relationship when filterOptions returns true', async () => {
|
||||
await payload.create({
|
||||
collection: relationTrueFilterOptionSlug,
|
||||
@@ -393,7 +397,8 @@ describe('fields - relationship', () => {
|
||||
await expect(options).toContainText('truth')
|
||||
})
|
||||
|
||||
test('should open document drawer from read-only relationships', async () => {
|
||||
// TODO: Flaky test in CI - fix.
|
||||
test.skip('should open document drawer from read-only relationships', async () => {
|
||||
const editURL = url.edit(docWithExistingRelations.id)
|
||||
await page.goto(editURL)
|
||||
await page.waitForURL(editURL)
|
||||
|
||||
@@ -17,6 +17,7 @@ import { AdminUrlUtil } from '../../../helpers/adminUrlUtil.js'
|
||||
import { initPayloadE2ENoConfig } from '../../../helpers/initPayloadE2ENoConfig.js'
|
||||
import { reInitializeDB } from '../../../helpers/reInitializeDB.js'
|
||||
import { RESTClient } from '../../../helpers/rest.js'
|
||||
import { TEST_TIMEOUT_LONG } from '../../../playwright.config.js'
|
||||
|
||||
const filename = fileURLToPath(import.meta.url)
|
||||
const currentFolder = path.dirname(filename)
|
||||
@@ -31,7 +32,9 @@ let serverURL: string
|
||||
// If we want to make this run in parallel: test.describe.configure({ mode: 'parallel' })
|
||||
|
||||
describe('Array', () => {
|
||||
beforeAll(async ({ browser }) => {
|
||||
beforeAll(async ({ browser }, testInfo) => {
|
||||
testInfo.setTimeout(TEST_TIMEOUT_LONG)
|
||||
|
||||
process.env.SEED_IN_CONFIG_ONINIT = 'false' // Makes it so the payload config onInit seed is not run. Otherwise, the seed would be run unnecessarily twice for the initial test run - once for beforeEach and once for onInit
|
||||
;({ payload, serverURL } = await initPayloadE2ENoConfig({
|
||||
dirname,
|
||||
@@ -40,6 +43,12 @@ describe('Array', () => {
|
||||
const context = await browser.newContext()
|
||||
page = await context.newPage()
|
||||
initPageConsoleErrorCatch(page)
|
||||
await reInitializeDB({
|
||||
serverURL,
|
||||
snapshotKey: 'fieldsArrayTest',
|
||||
uploadsDir: path.resolve(dirname, '../Upload/uploads'),
|
||||
})
|
||||
await ensureAutoLoginAndCompilationIsDone({ page, serverURL })
|
||||
})
|
||||
beforeEach(async () => {
|
||||
await reInitializeDB({
|
||||
|
||||
@@ -13,6 +13,7 @@ import { AdminUrlUtil } from '../../../helpers/adminUrlUtil.js'
|
||||
import { initPayloadE2ENoConfig } from '../../../helpers/initPayloadE2ENoConfig.js'
|
||||
import { reInitializeDB } from '../../../helpers/reInitializeDB.js'
|
||||
import { RESTClient } from '../../../helpers/rest.js'
|
||||
import { TEST_TIMEOUT_LONG } from '../../../playwright.config.js'
|
||||
|
||||
const filename = fileURLToPath(import.meta.url)
|
||||
const currentFolder = path.dirname(filename)
|
||||
@@ -26,7 +27,9 @@ let serverURL: string
|
||||
// If we want to make this run in parallel: test.describe.configure({ mode: 'parallel' })
|
||||
|
||||
describe('Block fields', () => {
|
||||
beforeAll(async ({ browser }) => {
|
||||
beforeAll(async ({ browser }, testInfo) => {
|
||||
testInfo.setTimeout(TEST_TIMEOUT_LONG)
|
||||
|
||||
process.env.SEED_IN_CONFIG_ONINIT = 'false' // Makes it so the payload config onInit seed is not run. Otherwise, the seed would be run unnecessarily twice for the initial test run - once for beforeEach and once for onInit
|
||||
;({ serverURL } = await initPayloadE2ENoConfig({
|
||||
dirname,
|
||||
@@ -35,6 +38,12 @@ describe('Block fields', () => {
|
||||
const context = await browser.newContext()
|
||||
page = await context.newPage()
|
||||
initPageConsoleErrorCatch(page)
|
||||
await reInitializeDB({
|
||||
serverURL,
|
||||
snapshotKey: 'blockFieldsTest',
|
||||
uploadsDir: path.resolve(dirname, '../Upload/uploads'),
|
||||
})
|
||||
await ensureAutoLoginAndCompilationIsDone({ page, serverURL })
|
||||
})
|
||||
beforeEach(async () => {
|
||||
await reInitializeDB({
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { SerializedBlockNode, SerializedLinkNode } from '@payloadcms/richtext-lexical'
|
||||
import type { Page } from '@playwright/test'
|
||||
import type { BrowserContext, Page } from '@playwright/test'
|
||||
import type { PayloadTestSDK } from 'helpers/sdk/index.js'
|
||||
import type { SerializedEditorState, SerializedParagraphNode, SerializedTextNode } from 'lexical'
|
||||
|
||||
@@ -12,10 +12,15 @@ import { fileURLToPath } from 'url'
|
||||
|
||||
import type { Config, LexicalField, Upload } from '../../payload-types.js'
|
||||
|
||||
import { initPageConsoleErrorCatch, saveDocAndAssert } from '../../../helpers.js'
|
||||
import {
|
||||
ensureAutoLoginAndCompilationIsDone,
|
||||
initPageConsoleErrorCatch,
|
||||
saveDocAndAssert,
|
||||
throttleTest,
|
||||
} from '../../../helpers.js'
|
||||
import { AdminUrlUtil } from '../../../helpers/adminUrlUtil.js'
|
||||
import { RESTClient } from '../../../helpers/rest.js'
|
||||
import { POLL_TOPASS_TIMEOUT } from '../../../playwright.config.js'
|
||||
import { POLL_TOPASS_TIMEOUT, TEST_TIMEOUT_LONG } from '../../../playwright.config.js'
|
||||
import { lexicalFieldsSlug } from '../../slugs.js'
|
||||
import { lexicalDocData } from './data.js'
|
||||
|
||||
@@ -28,6 +33,7 @@ const { beforeAll, beforeEach, describe } = test
|
||||
let payload: PayloadTestSDK<Config>
|
||||
let client: RESTClient
|
||||
let page: Page
|
||||
let context: BrowserContext
|
||||
let serverURL: string
|
||||
|
||||
/**
|
||||
@@ -55,16 +61,28 @@ async function navigateToLexicalFields(
|
||||
}
|
||||
|
||||
describe('lexical', () => {
|
||||
beforeAll(async ({ browser }) => {
|
||||
beforeAll(async ({ browser }, testInfo) => {
|
||||
testInfo.setTimeout(TEST_TIMEOUT_LONG)
|
||||
process.env.SEED_IN_CONFIG_ONINIT = 'false' // Makes it so the payload config onInit seed is not run. Otherwise, the seed would be run unnecessarily twice for the initial test run - once for beforeEach and once for onInit
|
||||
;({ payload, serverURL } = await initPayloadE2ENoConfig({ dirname }))
|
||||
|
||||
const context = await browser.newContext()
|
||||
context = await browser.newContext()
|
||||
page = await context.newPage()
|
||||
|
||||
initPageConsoleErrorCatch(page)
|
||||
await reInitializeDB({
|
||||
serverURL,
|
||||
snapshotKey: 'fieldsLexicalTest',
|
||||
uploadsDir: path.resolve(dirname, '../Upload/uploads'),
|
||||
})
|
||||
await ensureAutoLoginAndCompilationIsDone({ page, serverURL })
|
||||
})
|
||||
beforeEach(async () => {
|
||||
/*await throttleTest({
|
||||
page,
|
||||
context,
|
||||
delay: 'Slow 4G',
|
||||
})*/
|
||||
await reInitializeDB({
|
||||
serverURL,
|
||||
snapshotKey: 'fieldsLexicalTest',
|
||||
|
||||
@@ -20,7 +20,7 @@ import { AdminUrlUtil } from '../../../helpers/adminUrlUtil.js'
|
||||
import { initPayloadE2ENoConfig } from '../../../helpers/initPayloadE2ENoConfig.js'
|
||||
import { reInitializeDB } from '../../../helpers/reInitializeDB.js'
|
||||
import { RESTClient } from '../../../helpers/rest.js'
|
||||
import { POLL_TOPASS_TIMEOUT } from '../../../playwright.config.js'
|
||||
import { POLL_TOPASS_TIMEOUT, TEST_TIMEOUT_LONG } from '../../../playwright.config.js'
|
||||
import { relationshipFieldsSlug, textFieldsSlug } from '../../slugs.js'
|
||||
const filename = fileURLToPath(import.meta.url)
|
||||
const currentFolder = path.dirname(filename)
|
||||
@@ -35,7 +35,8 @@ let serverURL: string
|
||||
// If we want to make this run in parallel: test.describe.configure({ mode: 'parallel' })
|
||||
|
||||
describe('relationship', () => {
|
||||
beforeAll(async ({ browser }) => {
|
||||
beforeAll(async ({ browser }, testInfo) => {
|
||||
testInfo.setTimeout(TEST_TIMEOUT_LONG)
|
||||
process.env.SEED_IN_CONFIG_ONINIT = 'false' // Makes it so the payload config onInit seed is not run. Otherwise, the seed would be run unnecessarily twice for the initial test run - once for beforeEach and once for onInit
|
||||
;({ payload, serverURL } = await initPayloadE2ENoConfig({
|
||||
dirname,
|
||||
@@ -44,6 +45,12 @@ describe('relationship', () => {
|
||||
const context = await browser.newContext()
|
||||
page = await context.newPage()
|
||||
initPageConsoleErrorCatch(page)
|
||||
await reInitializeDB({
|
||||
serverURL,
|
||||
snapshotKey: 'fieldsRelationshipTest',
|
||||
uploadsDir: path.resolve(dirname, '../Upload/uploads'),
|
||||
})
|
||||
await ensureAutoLoginAndCompilationIsDone({ page, serverURL })
|
||||
})
|
||||
beforeEach(async () => {
|
||||
await reInitializeDB({
|
||||
@@ -163,7 +170,8 @@ describe('relationship', () => {
|
||||
expect(count).toEqual(0)
|
||||
})
|
||||
|
||||
test('should clear relationship values', async () => {
|
||||
// TODO: Flaky test in CI - fix this. https://github.com/payloadcms/payload/actions/runs/8910825395/job/24470963991
|
||||
test.skip('should clear relationship values', async () => {
|
||||
await page.goto(url.create)
|
||||
|
||||
const field = page.locator('#field-relationship')
|
||||
@@ -380,9 +388,12 @@ describe('relationship', () => {
|
||||
test('should sort relationship options by sortOptions property (ID in ascending order)', async () => {
|
||||
await page.goto(url.create)
|
||||
await page.waitForURL(url.create)
|
||||
await wait(400)
|
||||
|
||||
const field = page.locator('#field-relationship')
|
||||
await wait(400)
|
||||
await field.click()
|
||||
await wait(400)
|
||||
|
||||
const textDocsGroup = page.locator('.rs__group-heading:has-text("Text Fields")')
|
||||
const firstTextDocOption = textDocsGroup.locator('+div .rs__option').first()
|
||||
|
||||
@@ -14,6 +14,7 @@ import { AdminUrlUtil } from '../../../helpers/adminUrlUtil.js'
|
||||
import { initPayloadE2ENoConfig } from '../../../helpers/initPayloadE2ENoConfig.js'
|
||||
import { reInitializeDB } from '../../../helpers/reInitializeDB.js'
|
||||
import { RESTClient } from '../../../helpers/rest.js'
|
||||
import { POLL_TOPASS_TIMEOUT, TEST_TIMEOUT_LONG } from '../../../playwright.config.js'
|
||||
|
||||
const filename = fileURLToPath(import.meta.url)
|
||||
const currentFolder = path.dirname(filename)
|
||||
@@ -27,7 +28,8 @@ let serverURL: string
|
||||
// If we want to make this run in parallel: test.describe.configure({ mode: 'parallel' })
|
||||
|
||||
describe('Rich Text', () => {
|
||||
beforeAll(async ({ browser }) => {
|
||||
beforeAll(async ({ browser }, testInfo) => {
|
||||
testInfo.setTimeout(TEST_TIMEOUT_LONG)
|
||||
process.env.SEED_IN_CONFIG_ONINIT = 'false' // Makes it so the payload config onInit seed is not run. Otherwise, the seed would be run unnecessarily twice for the initial test run - once for beforeEach and once for onInit
|
||||
;({ serverURL } = await initPayloadE2ENoConfig({
|
||||
dirname,
|
||||
@@ -36,6 +38,12 @@ describe('Rich Text', () => {
|
||||
const context = await browser.newContext()
|
||||
page = await context.newPage()
|
||||
initPageConsoleErrorCatch(page)
|
||||
await reInitializeDB({
|
||||
serverURL,
|
||||
snapshotKey: 'fieldsRichTextTest',
|
||||
uploadsDir: path.resolve(dirname, '../Upload/uploads'),
|
||||
})
|
||||
await ensureAutoLoginAndCompilationIsDone({ page, serverURL })
|
||||
})
|
||||
beforeEach(async () => {
|
||||
await reInitializeDB({
|
||||
@@ -57,7 +65,14 @@ describe('Rich Text', () => {
|
||||
const url: AdminUrlUtil = new AdminUrlUtil(serverURL, 'rich-text-fields')
|
||||
await page.goto(url.list)
|
||||
await page.waitForURL(url.list)
|
||||
await page.locator('.row-1 .cell-title a').click()
|
||||
|
||||
const linkToDoc = page.locator('.row-1 .cell-title a').first()
|
||||
await expect(() => expect(linkToDoc).toBeTruthy()).toPass({ timeout: POLL_TOPASS_TIMEOUT })
|
||||
const linkDocHref = await linkToDoc.getAttribute('href')
|
||||
|
||||
await linkToDoc.click()
|
||||
|
||||
await page.waitForURL(`**${linkDocHref}`)
|
||||
}
|
||||
|
||||
describe('cell', () => {
|
||||
@@ -71,9 +86,19 @@ describe('Rich Text', () => {
|
||||
const entireRow = table.locator('.row-1').first()
|
||||
|
||||
// Make sure each of the 3 above are no larger than 300px in height:
|
||||
expect((await lexicalCell.boundingBox()).height).toBeLessThanOrEqual(300)
|
||||
expect((await lexicalHtmlCell.boundingBox()).height).toBeLessThanOrEqual(300)
|
||||
expect((await entireRow.boundingBox()).height).toBeLessThanOrEqual(300)
|
||||
await expect
|
||||
.poll(async () => (await lexicalCell.boundingBox()).height, {
|
||||
timeout: POLL_TOPASS_TIMEOUT,
|
||||
})
|
||||
.toBeLessThanOrEqual(300)
|
||||
await expect
|
||||
.poll(async () => (await lexicalHtmlCell.boundingBox()).height, {
|
||||
timeout: POLL_TOPASS_TIMEOUT,
|
||||
})
|
||||
.toBeLessThanOrEqual(300)
|
||||
await expect
|
||||
.poll(async () => (await entireRow.boundingBox()).height, { timeout: POLL_TOPASS_TIMEOUT })
|
||||
.toBeLessThanOrEqual(300)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -102,7 +127,8 @@ describe('Rich Text', () => {
|
||||
expect(hasErrorClass).toBe(true)
|
||||
})
|
||||
|
||||
test('should create new url custom link', async () => {
|
||||
// TODO: Flaky test flakes consistently in CI: https://github.com/payloadcms/payload/actions/runs/8913431889/job/24478995959?pr=6155
|
||||
test.skip('should create new url custom link', async () => {
|
||||
await navigateToRichTextFields()
|
||||
|
||||
// Open link drawer
|
||||
@@ -118,6 +144,7 @@ describe('Rich Text', () => {
|
||||
await editLinkModal.locator('label[for="field-linkType-custom"]').click()
|
||||
await editLinkModal.locator('#field-url').fill('https://payloadcms.com')
|
||||
await editLinkModal.locator('button[type="submit"]').click()
|
||||
await expect(editLinkModal).toBeHidden()
|
||||
await wait(400)
|
||||
await saveDocAndAssert(page)
|
||||
|
||||
@@ -129,7 +156,8 @@ describe('Rich Text', () => {
|
||||
await expect(page.locator('span >> text="link text"')).toHaveCount(0)
|
||||
})
|
||||
|
||||
test('should create new internal link', async () => {
|
||||
// TODO: Flaky test flakes consistently in CI: https://github.com/payloadcms/payload/actions/runs/8913769794/job/24480056251?pr=6155
|
||||
test.skip('should create new internal link', async () => {
|
||||
await navigateToRichTextFields()
|
||||
|
||||
// Open link drawer
|
||||
@@ -245,7 +273,8 @@ describe('Rich Text', () => {
|
||||
await expect(menu).not.toContainText('Uploads')
|
||||
})
|
||||
|
||||
test('should respect customizing the default fields', async () => {
|
||||
// TODO: Flaky test in CI. Flake: https://github.com/payloadcms/payload/actions/runs/8914532814/job/24482407114
|
||||
test.skip('should respect customizing the default fields', async () => {
|
||||
const linkText = 'link'
|
||||
const value = 'test value'
|
||||
await navigateToRichTextFields()
|
||||
|
||||
@@ -20,7 +20,7 @@ import { AdminUrlUtil } from '../helpers/adminUrlUtil.js'
|
||||
import { initPayloadE2ENoConfig } from '../helpers/initPayloadE2ENoConfig.js'
|
||||
import { reInitializeDB } from '../helpers/reInitializeDB.js'
|
||||
import { RESTClient } from '../helpers/rest.js'
|
||||
import { POLL_TOPASS_TIMEOUT } from '../playwright.config.js'
|
||||
import { POLL_TOPASS_TIMEOUT, TEST_TIMEOUT_LONG } from '../playwright.config.js'
|
||||
import { jsonDoc } from './collections/JSON/shared.js'
|
||||
import { numberDoc } from './collections/Number/shared.js'
|
||||
import { textDoc } from './collections/Text/shared.js'
|
||||
@@ -37,7 +37,8 @@ let serverURL: string
|
||||
// If we want to make this run in parallel: test.describe.configure({ mode: 'parallel' })
|
||||
|
||||
describe('fields', () => {
|
||||
beforeAll(async ({ browser }) => {
|
||||
beforeAll(async ({ browser }, testInfo) => {
|
||||
testInfo.setTimeout(TEST_TIMEOUT_LONG)
|
||||
process.env.SEED_IN_CONFIG_ONINIT = 'false' // Makes it so the payload config onInit seed is not run. Otherwise, the seed would be run unnecessarily twice for the initial test run - once for beforeEach and once for onInit
|
||||
;({ payload, serverURL } = await initPayloadE2ENoConfig({
|
||||
dirname,
|
||||
@@ -47,6 +48,12 @@ describe('fields', () => {
|
||||
const context = await browser.newContext()
|
||||
page = await context.newPage()
|
||||
initPageConsoleErrorCatch(page)
|
||||
await reInitializeDB({
|
||||
serverURL,
|
||||
snapshotKey: 'fieldsTest',
|
||||
uploadsDir: path.resolve(dirname, './collections/Upload/uploads'),
|
||||
})
|
||||
await ensureAutoLoginAndCompilationIsDone({ page, serverURL })
|
||||
})
|
||||
beforeEach(async () => {
|
||||
await reInitializeDB({
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import type { BrowserContext, Locator, Page } from '@playwright/test'
|
||||
import type { BrowserContext, ChromiumBrowserContext, Locator, Page } from '@playwright/test'
|
||||
|
||||
import { expect } from '@playwright/test'
|
||||
import { wait } from 'payload/utilities'
|
||||
import shelljs from 'shelljs'
|
||||
import { setTimeout } from 'timers/promises'
|
||||
|
||||
import { devUser } from './credentials.js'
|
||||
import { POLL_TOPASS_TIMEOUT } from './playwright.config.js'
|
||||
@@ -20,6 +21,7 @@ type LoginArgs = {
|
||||
page: Page
|
||||
serverURL: string
|
||||
}
|
||||
const random = (min: number, max: number) => Math.floor(Math.random() * (max - min + 1)) + min
|
||||
|
||||
const networkConditions = {
|
||||
'Slow 3G': {
|
||||
@@ -61,9 +63,14 @@ export async function ensureAutoLoginAndCompilationIsDone({
|
||||
await expect(() => expect(page.url()).not.toContain(`/admin/create-first-user`)).toPass({
|
||||
timeout: POLL_TOPASS_TIMEOUT,
|
||||
})
|
||||
// Check if hero is there
|
||||
await expect(page.locator('.dashboard__label').first()).toBeVisible()
|
||||
}
|
||||
|
||||
export async function delayNetwork({
|
||||
/**
|
||||
* CPU throttling & 2 different kinds of network throttling
|
||||
*/
|
||||
export async function throttleTest({
|
||||
context,
|
||||
page,
|
||||
delay,
|
||||
@@ -80,6 +87,14 @@ export async function delayNetwork({
|
||||
latency: networkConditions[delay].latency,
|
||||
offline: false,
|
||||
})
|
||||
|
||||
await page.route('**/*', async (route) => {
|
||||
await setTimeout(random(500, 1000))
|
||||
await route.continue()
|
||||
})
|
||||
|
||||
const client = await (page.context() as ChromiumBrowserContext).newCDPSession(page)
|
||||
await client.send('Emulation.setCPUThrottlingRate', { rate: 8 }) // 8x slowdown
|
||||
}
|
||||
|
||||
export async function firstRegister(args: FirstRegisterArgs): Promise<void> {
|
||||
|
||||
@@ -13,7 +13,7 @@ import {
|
||||
} from '../helpers.js'
|
||||
import { AdminUrlUtil } from '../helpers/adminUrlUtil.js'
|
||||
import { initPayloadE2ENoConfig } from '../helpers/initPayloadE2ENoConfig.js'
|
||||
import { POLL_TOPASS_TIMEOUT } from '../playwright.config.js'
|
||||
import { POLL_TOPASS_TIMEOUT, TEST_TIMEOUT_LONG } from '../playwright.config.js'
|
||||
import { mobileBreakpoint } from './shared.js'
|
||||
const filename = fileURLToPath(import.meta.url)
|
||||
const dirname = path.dirname(filename)
|
||||
@@ -44,7 +44,8 @@ describe('Live Preview', () => {
|
||||
await page.waitForURL(previewURL)
|
||||
}
|
||||
|
||||
beforeAll(async ({ browser }) => {
|
||||
beforeAll(async ({ browser }, testInfo) => {
|
||||
testInfo.setTimeout(TEST_TIMEOUT_LONG)
|
||||
;({ serverURL } = await initPayloadE2ENoConfig({ dirname }))
|
||||
url = new AdminUrlUtil(serverURL, 'pages')
|
||||
const context = await browser.newContext()
|
||||
|
||||
@@ -17,7 +17,7 @@ import {
|
||||
} from '../helpers.js'
|
||||
import { AdminUrlUtil } from '../helpers/adminUrlUtil.js'
|
||||
import { initPayloadE2ENoConfig } from '../helpers/initPayloadE2ENoConfig.js'
|
||||
import { POLL_TOPASS_TIMEOUT } from '../playwright.config.js'
|
||||
import { POLL_TOPASS_TIMEOUT, TEST_TIMEOUT_LONG } from '../playwright.config.js'
|
||||
import {
|
||||
englishTitle,
|
||||
localizedPostsSlug,
|
||||
@@ -51,7 +51,8 @@ let payload: PayloadTestSDK<Config>
|
||||
let serverURL: string
|
||||
|
||||
describe('Localization', () => {
|
||||
beforeAll(async ({ browser }) => {
|
||||
beforeAll(async ({ browser }, testInfo) => {
|
||||
testInfo.setTimeout(TEST_TIMEOUT_LONG)
|
||||
;({ payload, serverURL } = await initPayloadE2ENoConfig({ dirname }))
|
||||
|
||||
url = new AdminUrlUtil(serverURL, localizedPostsSlug)
|
||||
|
||||
@@ -4,7 +4,7 @@ import baseConfig from './playwright.config.js'
|
||||
|
||||
const config: PlaywrightTestConfig = {
|
||||
...baseConfig,
|
||||
maxFailures: 1,
|
||||
maxFailures: process.env.CI ? undefined : 1,
|
||||
}
|
||||
|
||||
export default config
|
||||
|
||||
@@ -8,14 +8,16 @@ const dirname = path.dirname(filename)
|
||||
|
||||
dotenv.config({ path: path.resolve(dirname, 'test.env') })
|
||||
|
||||
export const EXPECT_TIMEOUT = 45000
|
||||
export const TEST_TIMEOUT_LONG = 480000 // 8 minutes - used as timeOut for the beforeAll
|
||||
export const TEST_TIMEOUT = 60000
|
||||
export const EXPECT_TIMEOUT = 8000
|
||||
export const POLL_TOPASS_TIMEOUT = EXPECT_TIMEOUT * 4 // That way expect.poll() or expect().toPass can retry 4 times. 4x higher than default expect timeout => can retry 4 times if retryable expects are used inside
|
||||
|
||||
export default defineConfig({
|
||||
// Look for test files in the "test" directory, relative to this configuration file
|
||||
testDir: '',
|
||||
testMatch: '*e2e.spec.ts',
|
||||
timeout: 120000,
|
||||
timeout: TEST_TIMEOUT, // 1 minute
|
||||
use: {
|
||||
screenshot: 'only-on-failure',
|
||||
trace: 'retain-on-failure',
|
||||
@@ -25,5 +27,9 @@ export default defineConfig({
|
||||
timeout: EXPECT_TIMEOUT,
|
||||
},
|
||||
workers: 16,
|
||||
maxFailures: process.env.CI ? 1 : undefined,
|
||||
maxFailures: process.env.CI ? undefined : undefined,
|
||||
retries: process.env.CI ? 5 : undefined,
|
||||
reporter: process.env.CI
|
||||
? [['list', { printSteps: true }], ['json']]
|
||||
: [['list', { printSteps: true }]],
|
||||
})
|
||||
|
||||
@@ -4,9 +4,10 @@ import { expect, test } from '@playwright/test'
|
||||
import * as path from 'path'
|
||||
import { fileURLToPath } from 'url'
|
||||
|
||||
import { saveDocAndAssert } from '../helpers.js'
|
||||
import { ensureAutoLoginAndCompilationIsDone, saveDocAndAssert } from '../helpers.js'
|
||||
import { AdminUrlUtil } from '../helpers/adminUrlUtil.js'
|
||||
import { initPayloadE2ENoConfig } from '../helpers/initPayloadE2ENoConfig.js'
|
||||
import { TEST_TIMEOUT_LONG } from '../playwright.config.js'
|
||||
import { mediaSlug } from './shared.js'
|
||||
|
||||
const filename = fileURLToPath(import.meta.url)
|
||||
@@ -16,12 +17,14 @@ test.describe('Admin Panel', () => {
|
||||
let page: Page
|
||||
let mediaURL: AdminUrlUtil
|
||||
|
||||
test.beforeAll(async ({ browser }) => {
|
||||
test.beforeAll(async ({ browser }, testInfo) => {
|
||||
testInfo.setTimeout(TEST_TIMEOUT_LONG)
|
||||
const { serverURL } = await initPayloadE2ENoConfig({ dirname })
|
||||
mediaURL = new AdminUrlUtil(serverURL, mediaSlug)
|
||||
|
||||
const context = await browser.newContext()
|
||||
page = await context.newPage()
|
||||
await ensureAutoLoginAndCompilationIsDone({ page, serverURL })
|
||||
})
|
||||
|
||||
test('should create file upload', async () => {
|
||||
|
||||
@@ -10,7 +10,7 @@ import type { Config } from './payload-types.js'
|
||||
import { ensureAutoLoginAndCompilationIsDone, initPageConsoleErrorCatch } from '../helpers.js'
|
||||
import { AdminUrlUtil } from '../helpers/adminUrlUtil.js'
|
||||
import { initPayloadE2ENoConfig } from '../helpers/initPayloadE2ENoConfig.js'
|
||||
import { POLL_TOPASS_TIMEOUT } from '../playwright.config.js'
|
||||
import { POLL_TOPASS_TIMEOUT, TEST_TIMEOUT_LONG } from '../playwright.config.js'
|
||||
|
||||
const filename = fileURLToPath(import.meta.url)
|
||||
const dirname = path.dirname(filename)
|
||||
@@ -21,7 +21,8 @@ test.describe('Form Builder', () => {
|
||||
let submissionsUrl: AdminUrlUtil
|
||||
let payload: PayloadTestSDK<Config>
|
||||
|
||||
test.beforeAll(async ({ browser }) => {
|
||||
test.beforeAll(async ({ browser }, testInfo) => {
|
||||
testInfo.setTimeout(TEST_TIMEOUT_LONG)
|
||||
const { payload: payloadFromInit, serverURL } = await initPayloadE2ENoConfig<Config>({
|
||||
dirname,
|
||||
})
|
||||
|
||||
@@ -9,6 +9,7 @@ import type { Config, Page as PayloadPage } from './payload-types.js'
|
||||
import { ensureAutoLoginAndCompilationIsDone, initPageConsoleErrorCatch } from '../helpers.js'
|
||||
import { AdminUrlUtil } from '../helpers/adminUrlUtil.js'
|
||||
import { initPayloadE2ENoConfig } from '../helpers/initPayloadE2ENoConfig.js'
|
||||
import { TEST_TIMEOUT_LONG } from '../playwright.config.js'
|
||||
const filename = fileURLToPath(import.meta.url)
|
||||
const dirname = path.dirname(filename)
|
||||
|
||||
@@ -21,7 +22,8 @@ let draftChildId: string
|
||||
let childId: string
|
||||
|
||||
describe('Nested Docs Plugin', () => {
|
||||
beforeAll(async ({ browser }) => {
|
||||
beforeAll(async ({ browser }, testInfo) => {
|
||||
testInfo.setTimeout(TEST_TIMEOUT_LONG)
|
||||
const { serverURL, payload } = await initPayloadE2ENoConfig<Config>({ dirname })
|
||||
url = new AdminUrlUtil(serverURL, 'pages')
|
||||
const context = await browser.newContext()
|
||||
|
||||
@@ -3,6 +3,7 @@ import type { Page } from '@playwright/test'
|
||||
import { expect, test } from '@playwright/test'
|
||||
import path from 'path'
|
||||
import { getFileByPath } from 'payload/uploads'
|
||||
import { wait } from 'payload/utilities'
|
||||
import { fileURLToPath } from 'url'
|
||||
|
||||
import type { Config, Page as PayloadPage } from './payload-types.js'
|
||||
@@ -10,6 +11,7 @@ import type { Config, Page as PayloadPage } from './payload-types.js'
|
||||
import { ensureAutoLoginAndCompilationIsDone, initPageConsoleErrorCatch } from '../helpers.js'
|
||||
import { AdminUrlUtil } from '../helpers/adminUrlUtil.js'
|
||||
import { initPayloadE2ENoConfig } from '../helpers/initPayloadE2ENoConfig.js'
|
||||
import { TEST_TIMEOUT_LONG } from '../playwright.config.js'
|
||||
import { mediaSlug } from './shared.js'
|
||||
|
||||
const filename = fileURLToPath(import.meta.url)
|
||||
@@ -22,7 +24,8 @@ let page: Page
|
||||
let id: string
|
||||
|
||||
describe('SEO Plugin', () => {
|
||||
beforeAll(async ({ browser }) => {
|
||||
beforeAll(async ({ browser }, testInfo) => {
|
||||
testInfo.setTimeout(TEST_TIMEOUT_LONG)
|
||||
const { serverURL, payload } = await initPayloadE2ENoConfig<Config>({ dirname })
|
||||
url = new AdminUrlUtil(serverURL, 'pages')
|
||||
|
||||
@@ -149,13 +152,17 @@ describe('SEO Plugin', () => {
|
||||
|
||||
// Change language to Spanish
|
||||
await languageField.click()
|
||||
await wait(200)
|
||||
await options.locator('text=Español').click()
|
||||
await expect(languageField).toContainText('Español')
|
||||
await wait(600)
|
||||
|
||||
// Navigate back to the page
|
||||
await page.goto(url.edit(id))
|
||||
await wait(600)
|
||||
|
||||
await secondTab.click()
|
||||
await wait(600)
|
||||
|
||||
await expect(autoGenButton).toContainText('Auto-génerar')
|
||||
})
|
||||
|
||||
@@ -18,6 +18,7 @@ import {
|
||||
import { AdminUrlUtil } from '../helpers/adminUrlUtil.js'
|
||||
import { initPayloadE2ENoConfig } from '../helpers/initPayloadE2ENoConfig.js'
|
||||
import { RESTClient } from '../helpers/rest.js'
|
||||
import { TEST_TIMEOUT_LONG } from '../playwright.config.js'
|
||||
import {
|
||||
adminThumbnailFunctionSlug,
|
||||
adminThumbnailSizeSlug,
|
||||
@@ -44,7 +45,8 @@ describe('uploads', () => {
|
||||
let pngDoc: Media
|
||||
let audioDoc: Media
|
||||
|
||||
beforeAll(async ({ browser }) => {
|
||||
beforeAll(async ({ browser }, testInfo) => {
|
||||
testInfo.setTimeout(TEST_TIMEOUT_LONG)
|
||||
;({ payload, serverURL } = await initPayloadE2ENoConfig<Config>({ dirname }))
|
||||
client = new RESTClient(null, { defaultSlug: 'users', serverURL })
|
||||
await client.login()
|
||||
|
||||
@@ -44,7 +44,7 @@ import {
|
||||
import { AdminUrlUtil } from '../helpers/adminUrlUtil.js'
|
||||
import { initPayloadE2ENoConfig } from '../helpers/initPayloadE2ENoConfig.js'
|
||||
import { reInitializeDB } from '../helpers/reInitializeDB.js'
|
||||
import { POLL_TOPASS_TIMEOUT } from '../playwright.config.js'
|
||||
import { POLL_TOPASS_TIMEOUT, TEST_TIMEOUT_LONG } from '../playwright.config.js'
|
||||
import { titleToDelete } from './shared.js'
|
||||
import {
|
||||
autoSaveGlobalSlug,
|
||||
@@ -93,7 +93,9 @@ describe('versions', () => {
|
||||
let customIDURL: AdminUrlUtil
|
||||
let postURL: AdminUrlUtil
|
||||
|
||||
beforeAll(async ({ browser }) => {
|
||||
beforeAll(async ({ browser }, testInfo) => {
|
||||
testInfo.setTimeout(TEST_TIMEOUT_LONG)
|
||||
|
||||
process.env.SEED_IN_CONFIG_ONINIT = 'false' // Makes it so the payload config onInit seed is not run. Otherwise, the seed would be run unnecessarily twice for the initial test run - once for beforeEach and once for onInit
|
||||
;({ payload, serverURL } = await initPayloadE2ENoConfig<Config>({ dirname }))
|
||||
const context = await browser.newContext()
|
||||
|
||||
Reference in New Issue
Block a user