Skip to content

Commit e1f07ff

Browse files
authored
test: move draft validation tests from form-state to field error states test suite (#14599)
### What? Move draft-validation tests from #14584 into `field-error-states` test suite for simplicity
1 parent fd44d2b commit e1f07ff

File tree

7 files changed

+131
-158
lines changed

7 files changed

+131
-158
lines changed

test/field-error-states/collections/ValidateDraftsOn/index.ts

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,38 @@
1-
import type { CollectionConfig } from 'payload'
1+
import type { CollectionConfig, TextFieldSingleValidation } from 'payload'
22

33
import { collectionSlugs } from '../../shared.js'
44

55
export const ValidateDraftsOn: CollectionConfig = {
6-
slug: collectionSlugs.validateDraftsOn,
6+
slug: collectionSlugs.validateDraftsOn as 'validate-drafts-on',
77
fields: [
88
{
99
name: 'title',
1010
type: 'text',
1111
required: true,
1212
},
13+
{
14+
name: 'failValidation',
15+
type: 'checkbox',
16+
admin: {
17+
description:
18+
'Check this box to simulate a validation failure. The save button should remain enabled after the failure.',
19+
},
20+
defaultValue: false,
21+
},
22+
{
23+
name: 'validatedField',
24+
type: 'text',
25+
admin: {
26+
description:
27+
'This field will fail validation if "Fail Validation" checkbox is checked. This simulates validation failures from business logic, network errors, or third-party validation.',
28+
},
29+
validate: ((value, { data }) => {
30+
if ((data as any)?.failValidation) {
31+
return 'Validation failed: simulated validation error to test save button behavior.'
32+
}
33+
return true
34+
}) as TextFieldSingleValidation,
35+
},
1336
],
1437
versions: {
1538
drafts: {

test/field-error-states/e2e.spec.ts

Lines changed: 44 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import type { Page } from '@playwright/test'
22

33
import { expect, test } from '@playwright/test'
44
import { AdminUrlUtil } from 'helpers/adminUrlUtil.js'
5-
import { addArrayRow, openArrayRowActions, removeArrayRow } from 'helpers/e2e/fields/array/index.js'
5+
import { addArrayRow, removeArrayRow } from 'helpers/e2e/fields/array/index.js'
66
import path from 'path'
77
import { wait } from 'payload/shared'
88
import { fileURLToPath } from 'url'
@@ -29,12 +29,15 @@ describe('Field Error States', () => {
2929
beforeAll(async ({ browser }, testInfo) => {
3030
testInfo.setTimeout(TEST_TIMEOUT_LONG)
3131
;({ serverURL } = await initPayloadE2ENoConfig({ dirname }))
32-
validateDraftsOff = new AdminUrlUtil(serverURL, collectionSlugs.validateDraftsOff)
33-
validateDraftsOn = new AdminUrlUtil(serverURL, collectionSlugs.validateDraftsOn)
34-
validateDraftsOnAutosave = new AdminUrlUtil(serverURL, collectionSlugs.validateDraftsOnAutosave)
35-
prevValue = new AdminUrlUtil(serverURL, collectionSlugs.prevValue)
36-
prevValueRelation = new AdminUrlUtil(serverURL, collectionSlugs.prevValueRelation)
37-
errorFieldsURL = new AdminUrlUtil(serverURL, collectionSlugs.errorFields)
32+
validateDraftsOff = new AdminUrlUtil(serverURL, collectionSlugs.validateDraftsOff!)
33+
validateDraftsOn = new AdminUrlUtil(serverURL, collectionSlugs.validateDraftsOn!)
34+
validateDraftsOnAutosave = new AdminUrlUtil(
35+
serverURL,
36+
collectionSlugs.validateDraftsOnAutosave!,
37+
)
38+
prevValue = new AdminUrlUtil(serverURL, collectionSlugs.prevValue!)
39+
prevValueRelation = new AdminUrlUtil(serverURL, collectionSlugs.prevValueRelation!)
40+
errorFieldsURL = new AdminUrlUtil(serverURL, collectionSlugs.errorFields!)
3841
const context = await browser.newContext()
3942
page = await context.newPage()
4043
initPageConsoleErrorCatch(page)
@@ -94,6 +97,40 @@ describe('Field Error States', () => {
9497
await page.locator('#field-title').fill('')
9598
await saveDocAndAssert(page, '#action-save', 'error')
9699
})
100+
101+
test('should keep save draft button enabled after validation failure on update', async () => {
102+
await page.goto(validateDraftsOn.create)
103+
await page.locator('#field-title').fill('Test Document')
104+
await page.click('#action-save-draft')
105+
await expect(page.locator('.payload-toast-container .toast-success')).toBeVisible()
106+
107+
await page.waitForURL(/\/admin\/collections\/validate-drafts-on\/[a-zA-Z0-9]+/)
108+
109+
await page.locator('#field-title').fill('Modified Document')
110+
await page.locator('#field-failValidation').check()
111+
await page.locator('#field-validatedField').fill('This will fail')
112+
113+
await page.click('#action-save-draft')
114+
await expect(page.locator('.payload-toast-container .toast-error')).toBeVisible()
115+
116+
const saveDraftButton = page.locator('#action-save-draft')
117+
await expect(saveDraftButton).toBeEnabled()
118+
119+
await page.click('#action-save-draft')
120+
await expect(page.locator('.payload-toast-container .toast-error')).toBeVisible()
121+
})
122+
123+
test('should keep save draft button enabled after successful save when form is modified again', async () => {
124+
await page.goto(validateDraftsOn.create)
125+
await page.locator('#field-title').fill('Test Document')
126+
await page.click('#action-save-draft')
127+
await expect(page.locator('.payload-toast-container .toast-success')).toBeVisible()
128+
129+
await page.locator('#field-title').fill('Modified Document')
130+
131+
const saveDraftButton = page.locator('#action-save-draft')
132+
await expect(saveDraftButton).toBeEnabled()
133+
})
97134
})
98135

99136
describe('previous values', () => {

test/field-error-states/payload-types.ts

Lines changed: 61 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ export interface Config {
7474
'validate-drafts-on-autosave': ValidateDraftsOnAutosave;
7575
'prev-value': PrevValue;
7676
'prev-value-relation': PrevValueRelation;
77+
'payload-kv': PayloadKv;
7778
users: User;
7879
'payload-locked-documents': PayloadLockedDocument;
7980
'payload-preferences': PayloadPreference;
@@ -88,6 +89,7 @@ export interface Config {
8889
'validate-drafts-on-autosave': ValidateDraftsOnAutosaveSelect<false> | ValidateDraftsOnAutosaveSelect<true>;
8990
'prev-value': PrevValueSelect<false> | PrevValueSelect<true>;
9091
'prev-value-relation': PrevValueRelationSelect<false> | PrevValueRelationSelect<true>;
92+
'payload-kv': PayloadKvSelect<false> | PayloadKvSelect<true>;
9193
users: UsersSelect<false> | UsersSelect<true>;
9294
'payload-locked-documents': PayloadLockedDocumentsSelect<false> | PayloadLockedDocumentsSelect<true>;
9395
'payload-preferences': PayloadPreferencesSelect<false> | PayloadPreferencesSelect<true>;
@@ -179,7 +181,7 @@ export interface ErrorField {
179181
root: {
180182
type: string;
181183
children: {
182-
type: string;
184+
type: any;
183185
version: number;
184186
[k: string]: unknown;
185187
}[];
@@ -232,7 +234,7 @@ export interface ErrorField {
232234
root: {
233235
type: string;
234236
children: {
235-
type: string;
237+
type: any;
236238
version: number;
237239
[k: string]: unknown;
238240
}[];
@@ -286,7 +288,7 @@ export interface ErrorField {
286288
root: {
287289
type: string;
288290
children: {
289-
type: string;
291+
type: any;
290292
version: number;
291293
[k: string]: unknown;
292294
}[];
@@ -351,7 +353,7 @@ export interface Upload {
351353
root: {
352354
type: string;
353355
children: {
354-
type: string;
356+
type: any;
355357
version: number;
356358
[k: string]: unknown;
357359
}[];
@@ -381,6 +383,14 @@ export interface Upload {
381383
export interface ValidateDraftsOn {
382384
id: string;
383385
title: string;
386+
/**
387+
* Check this box to simulate a validation failure. The save button should remain enabled after the failure.
388+
*/
389+
failValidation?: boolean | null;
390+
/**
391+
* This field will fail validation if "Fail Validation" checkbox is checked. This simulates validation failures from business logic, network errors, or third-party validation.
392+
*/
393+
validatedField?: string | null;
384394
updatedAt: string;
385395
createdAt: string;
386396
_status?: ('draft' | 'published') | null;
@@ -392,6 +402,14 @@ export interface ValidateDraftsOn {
392402
export interface ValidateDraftsOff {
393403
id: string;
394404
title: string;
405+
/**
406+
* Check this box to simulate a validation failure. The save button should remain enabled after the failure.
407+
*/
408+
failValidation?: boolean | null;
409+
/**
410+
* This field will fail validation if "Fail Validation" checkbox is checked. This simulates validation failures from business logic, network errors, or third-party validation.
411+
*/
412+
validatedField?: string | null;
395413
updatedAt: string;
396414
createdAt: string;
397415
_status?: ('draft' | 'published') | null;
@@ -403,6 +421,14 @@ export interface ValidateDraftsOff {
403421
export interface ValidateDraftsOnAutosave {
404422
id: string;
405423
title: string;
424+
/**
425+
* Check this box to simulate a validation failure. The save button should remain enabled after the failure.
426+
*/
427+
failValidation?: boolean | null;
428+
/**
429+
* This field will fail validation if "Fail Validation" checkbox is checked. This simulates validation failures from business logic, network errors, or third-party validation.
430+
*/
431+
validatedField?: string | null;
406432
updatedAt: string;
407433
createdAt: string;
408434
_status?: ('draft' | 'published') | null;
@@ -428,6 +454,23 @@ export interface PrevValueRelation {
428454
updatedAt: string;
429455
createdAt: string;
430456
}
457+
/**
458+
* This interface was referenced by `Config`'s JSON-Schema
459+
* via the `definition` "payload-kv".
460+
*/
461+
export interface PayloadKv {
462+
id: string;
463+
key: string;
464+
data:
465+
| {
466+
[k: string]: unknown;
467+
}
468+
| unknown[]
469+
| string
470+
| number
471+
| boolean
472+
| null;
473+
}
431474
/**
432475
* This interface was referenced by `Config`'s JSON-Schema
433476
* via the `definition` "payload-locked-documents".
@@ -657,6 +700,8 @@ export interface UploadsSelect<T extends boolean = true> {
657700
*/
658701
export interface ValidateDraftsOnSelect<T extends boolean = true> {
659702
title?: T;
703+
failValidation?: T;
704+
validatedField?: T;
660705
updatedAt?: T;
661706
createdAt?: T;
662707
_status?: T;
@@ -667,6 +712,8 @@ export interface ValidateDraftsOnSelect<T extends boolean = true> {
667712
*/
668713
export interface ValidateDraftsOffSelect<T extends boolean = true> {
669714
title?: T;
715+
failValidation?: T;
716+
validatedField?: T;
670717
updatedAt?: T;
671718
createdAt?: T;
672719
_status?: T;
@@ -677,6 +724,8 @@ export interface ValidateDraftsOffSelect<T extends boolean = true> {
677724
*/
678725
export interface ValidateDraftsOnAutosaveSelect<T extends boolean = true> {
679726
title?: T;
727+
failValidation?: T;
728+
validatedField?: T;
680729
updatedAt?: T;
681730
createdAt?: T;
682731
_status?: T;
@@ -700,6 +749,14 @@ export interface PrevValueRelationSelect<T extends boolean = true> {
700749
updatedAt?: T;
701750
createdAt?: T;
702751
}
752+
/**
753+
* This interface was referenced by `Config`'s JSON-Schema
754+
* via the `definition` "payload-kv_select".
755+
*/
756+
export interface PayloadKvSelect<T extends boolean = true> {
757+
key?: T;
758+
data?: T;
759+
}
703760
/**
704761
* This interface was referenced by `Config`'s JSON-Schema
705762
* via the `definition` "users_select".

test/form-state/collections/DraftValidation/index.ts

Lines changed: 0 additions & 55 deletions
This file was deleted.

test/form-state/config.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,13 @@ import path from 'path'
44
import { buildConfigWithDefaults } from '../buildConfigWithDefaults.js'
55
import { devUser } from '../credentials.js'
66
import { AutosavePostsCollection } from './collections/Autosave/index.js'
7-
import { DraftValidationCollection } from './collections/DraftValidation/index.js'
87
import { PostsCollection, postsSlug } from './collections/Posts/index.js'
98

109
const filename = fileURLToPath(import.meta.url)
1110
const dirname = path.dirname(filename)
1211

1312
export default buildConfigWithDefaults({
14-
collections: [PostsCollection, AutosavePostsCollection, DraftValidationCollection],
13+
collections: [PostsCollection, AutosavePostsCollection],
1514
admin: {
1615
importMap: {
1716
baseDir: path.resolve(dirname),

0 commit comments

Comments
 (0)