diff --git a/tests/e2e/all-field-types.spec.ts b/tests/e2e/all-field-types.spec.ts new file mode 100644 index 00000000..e021fa57 --- /dev/null +++ b/tests/e2e/all-field-types.spec.ts @@ -0,0 +1,411 @@ +/** + * E2E tests for all SCF field types + * + * Tests all major field types in a single field group to verify: + * - Field rendering in the editor + * - Value input and persistence + * - Frontend output via the_content filter + */ +const { test, expect } = require( './fixtures' ); +const { + waitForMetaBoxes, + uploadImageViaModal, + selectSelect2Option, +} = require( './field-helpers' ); +const path = require( 'path' ); + +const PLUGIN_SLUG = 'secure-custom-fields'; +const TEST_PLUGIN_SLUG = 'scf-test-plugin-all-field-types'; + +// Test data for each field type +const TEST_DATA = { + text_field: 'Sample text value', + textarea_field: 'Multi-line\ntext content', + email_field: 'test@example.com', + url_field: 'https://example.com', + password_field: 'secret123', + number_field: '42', + range_field: '75', + select_field: 'option_2', + checkbox_values: [ 'check_a', 'check_b' ], + radio_field: 'radio_2', + button_group_field: 'button_2', + true_false_field: true, + date_picker_field: '2024-06-15', + time_picker_field: '14:30:00', + date_time_picker_field: '2024-06-15 14:30:00', + color_picker_field: '#ff5733', + wysiwyg_field: 'Rich text content', + link_url: 'https://wordpress.org', + link_title: 'WordPress', + group_text: 'Group text value', + group_number: '99', + repeater_row_1_text: 'Row 1 text', + repeater_row_1_number: '10', +}; + +test.describe( 'All Field Types', () => { + test.beforeAll( async ( { requestUtils } ) => { + await requestUtils.activatePlugin( PLUGIN_SLUG ); + await requestUtils.activatePlugin( TEST_PLUGIN_SLUG ); + } ); + + test.afterAll( async ( { requestUtils } ) => { + await requestUtils.deactivatePlugin( TEST_PLUGIN_SLUG ); + await requestUtils.deactivatePlugin( PLUGIN_SLUG ); + await requestUtils.deleteAllPosts(); + } ); + + test( 'should save and display all field types correctly', async ( { + page, + admin, + editor, + requestUtils, + } ) => { + // Create a new post + const post = await requestUtils.createPost( { + title: 'All Field Types Test', + status: 'draft', + } ); + + // Navigate to edit post page + await admin.editPost( post.id ); + + // Wait for meta boxes to load + await waitForMetaBoxes( page ); + + // === Text-based fields === + + // Text field + const textField = page.locator( + '.acf-field[data-name="text_field"] input[type="text"]' + ); + await textField.fill( TEST_DATA.text_field ); + await textField.blur(); + + // Textarea field + const textareaField = page.locator( + '.acf-field[data-name="textarea_field"] textarea' + ); + await textareaField.fill( TEST_DATA.textarea_field ); + await textareaField.blur(); + + // Email field + const emailField = page.locator( + '.acf-field[data-name="email_field"] input[type="email"]' + ); + await emailField.fill( TEST_DATA.email_field ); + await emailField.blur(); + + // URL field + const urlField = page.locator( + '.acf-field[data-name="url_field"] input[type="url"]' + ); + await urlField.fill( TEST_DATA.url_field ); + await urlField.blur(); + + // Password field + const passwordField = page.locator( + '.acf-field[data-name="password_field"] input[type="password"]' + ); + await passwordField.fill( TEST_DATA.password_field ); + await passwordField.blur(); + + // Number field + const numberField = page.locator( + '.acf-field[data-name="number_field"] input[type="number"]' + ); + await numberField.fill( TEST_DATA.number_field ); + await numberField.blur(); + + // Range field + const rangeField = page.locator( + '.acf-field[data-name="range_field"] input[type="range"]' + ); + await rangeField.fill( TEST_DATA.range_field ); + await rangeField.blur(); + + // === Selection fields === + + // Select field + const selectField = page.locator( + '.acf-field[data-name="select_field"] select' + ); + await selectField.selectOption( TEST_DATA.select_field ); + + // Checkbox field - check two options + for ( const value of TEST_DATA.checkbox_values ) { + const checkbox = page.locator( + `.acf-field[data-name="checkbox_field"] input[type="checkbox"][value="${ value }"]` + ); + await checkbox.check(); + } + + // Radio field + const radioButton = page.locator( + `.acf-field[data-name="radio_field"] input[type="radio"][value="${ TEST_DATA.radio_field }"]` + ); + await radioButton.check(); + + // Button group field - click the label element (styled as button) + const buttonGroupLabel = page.locator( + `.acf-field[data-name="button_group_field"] label:has-text("Button 2")` + ); + await buttonGroupLabel.click(); + + // True/false field + if ( TEST_DATA.true_false_field ) { + const trueFalseSwitch = page.locator( + '.acf-field[data-name="true_false_field"] .acf-switch' + ); + await trueFalseSwitch.click(); + } + + // === Date/time fields === + + // Date picker field - click to open and set value + const datePickerInput = page.locator( + '.acf-field[data-name="date_picker_field"] input[type="text"]' + ); + await datePickerInput.click(); + // Wait for datepicker to open + await page.waitForSelector( '.ui-datepicker', { state: 'visible' } ); + // Select a date (June 15, 2024) + await page.locator( '.ui-datepicker-year' ).selectOption( '2024' ); + await page.locator( '.ui-datepicker-month' ).selectOption( '5' ); // June is 5 (0-indexed) + await page + .locator( '.ui-datepicker-calendar td a:has-text("15")' ) + .click(); + + // Note: time_picker_field and date_time_picker_field are skipped as they + // use complex jQuery UI timepicker widgets that are difficult to automate. + // These can be tested manually or in a separate focused test. + + // === Content fields === + + // Color picker field - click the button to open picker, then fill input + const colorPickerButton = page.locator( + '.acf-field[data-name="color_picker_field"] .wp-color-result, .acf-field[data-name="color_picker_field"] button.wp-color-result' + ); + await colorPickerButton.click(); + const colorPickerInput = page.locator( + '.acf-field[data-name="color_picker_field"] input.wp-color-picker' + ); + await colorPickerInput.fill( TEST_DATA.color_picker_field ); + await page.click( 'body' ); // Close picker + + // WYSIWYG field - need to interact with TinyMCE + // Switch to text mode for easier input + const wysiwygTextTab = page.locator( + '.acf-field[data-name="wysiwyg_field"] .wp-switch-editor.switch-html' + ); + if ( await wysiwygTextTab.isVisible() ) { + await wysiwygTextTab.click(); + } + const wysiwygTextarea = page.locator( + '.acf-field[data-name="wysiwyg_field"] textarea.wp-editor-area' + ); + await wysiwygTextarea.fill( `

${ TEST_DATA.wysiwyg_field }

` ); + + // Link field - click button to open WordPress link modal + const linkButton = page.locator( + '.acf-field[data-name="link_field"] button:has-text("Select Link"), .acf-field[data-name="link_field"] a:has-text("Select Link")' + ); + await linkButton.click(); + // Wait for WordPress link modal to open + const wpLinkUrlInput = page.locator( '#wp-link-url' ); + await wpLinkUrlInput.waitFor( { state: 'visible' } ); + await wpLinkUrlInput.fill( TEST_DATA.link_url ); + const wpLinkTextInput = page.locator( '#wp-link-text' ); + await wpLinkTextInput.fill( TEST_DATA.link_title ); + const submitButton = page.locator( '#wp-link-submit' ); + await submitButton.click(); + + // === Media field === + + // Image field - upload test image + const imageButton = page.locator( + '.acf-field[data-name="image_field"] .acf-image-uploader a[data-name="add"]' + ); + await imageButton.click(); + const imagePath = path.join( __dirname, 'assets', 'test-image.png' ); + await uploadImageViaModal( page, imagePath ); + + // === Relationship fields === + + // User field - select the current user (admin) + await selectSelect2Option( + page, + '.acf-field[data-name="user_field"]', + 'admin', + 'admin' + ); + + // Taxonomy field - use Select2 to select Uncategorized + await selectSelect2Option( + page, + '.acf-field[data-name="taxonomy_field"]', + 'Uncategorized', + 'Uncategorized' + ); + + // === Container fields === + + // Group field - fill sub-fields + const groupTextField = page.locator( + '.acf-field[data-name="group_field"] .acf-field[data-name="group_text"] input[type="text"]' + ); + await groupTextField.fill( TEST_DATA.group_text ); + await groupTextField.blur(); + + const groupNumberField = page.locator( + '.acf-field[data-name="group_field"] .acf-field[data-name="group_number"] input[type="number"]' + ); + await groupNumberField.fill( TEST_DATA.group_number ); + await groupNumberField.blur(); + + // Repeater field - add a row and fill it + const addRowButton = page.locator( + '.acf-field[data-name="repeater_field"] .acf-button[data-event="add-row"]' + ); + await addRowButton.click(); + + // Wait for new row to appear + const repeaterTextField = page.locator( + '.acf-field[data-name="repeater_field"] .acf-row:not(.acf-clone) .acf-field[data-name="repeater_text"] input[type="text"]' + ); + await repeaterTextField.waitFor( { state: 'visible' } ); + await repeaterTextField.fill( TEST_DATA.repeater_row_1_text ); + await repeaterTextField.blur(); + + const repeaterNumberField = page.locator( + '.acf-field[data-name="repeater_field"] .acf-row:not(.acf-clone) .acf-field[data-name="repeater_number"] input[type="number"]' + ); + await repeaterNumberField.fill( TEST_DATA.repeater_row_1_number ); + await repeaterNumberField.blur(); + + // === Verify on frontend === + + // Open preview page + const previewPage = await editor.openPreviewPage(); + + // Verify text field + const textOutput = previewPage.locator( '#scf-test-text_field' ); + await expect( textOutput ).toContainText( TEST_DATA.text_field ); + + // Verify textarea field + const textareaOutput = previewPage.locator( + '#scf-test-textarea_field' + ); + await expect( textareaOutput ).toContainText( 'Multi-line' ); + + // Verify email field + const emailOutput = previewPage.locator( '#scf-test-email_field' ); + await expect( emailOutput ).toContainText( TEST_DATA.email_field ); + + // Verify URL field + const urlOutput = previewPage.locator( '#scf-test-url_field' ); + await expect( urlOutput ).toContainText( TEST_DATA.url_field ); + + // Verify number field + const numberOutput = previewPage.locator( '#scf-test-number_field' ); + await expect( numberOutput ).toContainText( TEST_DATA.number_field ); + + // Verify range field + const rangeOutput = previewPage.locator( '#scf-test-range_field' ); + await expect( rangeOutput ).toContainText( TEST_DATA.range_field ); + + // Verify select field + const selectOutput = previewPage.locator( '#scf-test-select_field' ); + await expect( selectOutput ).toContainText( TEST_DATA.select_field ); + + // Verify checkbox field + const checkboxOutput = previewPage.locator( + '#scf-test-checkbox_field' + ); + await expect( checkboxOutput ).toContainText( 'check_a' ); + await expect( checkboxOutput ).toContainText( 'check_b' ); + + // Verify radio field + const radioOutput = previewPage.locator( '#scf-test-radio_field' ); + await expect( radioOutput ).toContainText( TEST_DATA.radio_field ); + + // Verify button group field + const buttonGroupOutput = previewPage.locator( + '#scf-test-button_group_field' + ); + await expect( buttonGroupOutput ).toContainText( + TEST_DATA.button_group_field + ); + + // Verify true/false field + const trueFalseOutput = previewPage.locator( + '#scf-test-true_false_field' + ); + await expect( trueFalseOutput ).toContainText( 'Yes' ); + + // Verify date picker field + const datePickerOutput = previewPage.locator( + '#scf-test-date_picker_field' + ); + await expect( datePickerOutput ).toContainText( '2024-06-15' ); + + // Note: time_picker_field and date_time_picker_field verification skipped + // as these fields are not filled in the test (complex jQuery UI widgets) + + // Verify color picker field + const colorOutput = previewPage.locator( + '#scf-test-color_picker_field' + ); + await expect( colorOutput ).toContainText( + TEST_DATA.color_picker_field + ); + + // Verify WYSIWYG field + const wysiwygOutput = previewPage.locator( '#scf-test-wysiwyg_field' ); + await expect( wysiwygOutput ).toContainText( TEST_DATA.wysiwyg_field ); + + // Verify link field + const linkOutput = previewPage.locator( '#scf-test-link_field a' ); + await expect( linkOutput ).toHaveAttribute( + 'href', + TEST_DATA.link_url + ); + await expect( linkOutput ).toContainText( TEST_DATA.link_title ); + + // Verify image field + const imageOutput = previewPage.locator( + '#scf-test-image_field img.scf-test-image' + ); + await expect( imageOutput ).toBeVisible(); + + // Verify user field + const userOutput = previewPage.locator( '#scf-test-user_field' ); + await expect( userOutput ).toContainText( 'admin' ); + + // Verify taxonomy field + const taxonomyOutput = previewPage.locator( + '#scf-test-taxonomy_field' + ); + await expect( taxonomyOutput ).toContainText( 'Uncategorized' ); + + // Verify group field + const groupOutput = previewPage.locator( '#scf-test-group_field' ); + await expect( groupOutput ).toContainText( TEST_DATA.group_text ); + await expect( groupOutput ).toContainText( TEST_DATA.group_number ); + + // Verify repeater field + const repeaterOutput = previewPage.locator( + '#scf-test-repeater_field' + ); + await expect( repeaterOutput ).toContainText( + TEST_DATA.repeater_row_1_text + ); + await expect( repeaterOutput ).toContainText( + TEST_DATA.repeater_row_1_number + ); + + // Close preview page + await previewPage.close(); + } ); +} ); diff --git a/tests/e2e/block-bindings-site-editor.spec.ts b/tests/e2e/block-bindings-site-editor.spec.ts index b087318e..50234ead 100644 --- a/tests/e2e/block-bindings-site-editor.spec.ts +++ b/tests/e2e/block-bindings-site-editor.spec.ts @@ -115,7 +115,8 @@ test.describe( 'Block Bindings in Site Editor', () => { const emptyParagraph = frameLocator.locator( '[data-type="core/paragraph"][data-empty="true"]' ); - await emptyParagraph.click(); + // Force click to bypass WP 7.0's side-inserter popover overlay. + await emptyParagraph.click( { force: true } ); // Wait for the "Connect to a field" panel to appear in the block inspector await page.waitForSelector( diff --git a/tests/e2e/block-v3-features.spec.ts b/tests/e2e/block-v3-features.spec.ts new file mode 100644 index 00000000..cf346b34 --- /dev/null +++ b/tests/e2e/block-v3-features.spec.ts @@ -0,0 +1,329 @@ +/** + * E2E tests for SCF Block V3 features + * + * Tests the block version 3 specific functionality: + * - Preview-only rendering (no edit mode toggle) + * - Real-time sidebar field updates to preview + * - Required field validation + */ +const { test, expect, wpVersionAtLeast } = require( './fixtures' ); + +const PLUGIN_SLUG = 'secure-custom-fields'; +const TEST_PLUGIN_SLUG = 'scf-test-plugin-v3-block'; +const BLOCK_NAME = 'scf/v3-block'; + +test.describe( 'SCF Block V3 Features', () => { + test.beforeAll( async ( { requestUtils } ) => { + await requestUtils.activatePlugin( PLUGIN_SLUG ); + await requestUtils.activatePlugin( TEST_PLUGIN_SLUG ); + } ); + + test.afterAll( async ( { requestUtils } ) => { + await requestUtils.deactivatePlugin( TEST_PLUGIN_SLUG ); + await requestUtils.deactivatePlugin( PLUGIN_SLUG ); + await requestUtils.deleteAllPosts(); + } ); + + test.beforeEach( async ( { page } ) => { + // ACF block version 3 requires WordPress 6.3+ + await page.goto( '/wp-admin/' ); + test.skip( + ! ( await wpVersionAtLeast( page, 6, 3 ) ), + 'ACF block version 3 requires WordPress 6.3+' + ); + } ); + + test( 'should render v3 block in preview-only mode', async ( { + page, + admin, + editor, + requestUtils, + } ) => { + // Create a new post + const post = await requestUtils.createPost( { + title: 'V3 Block Preview Test', + status: 'draft', + } ); + + // Navigate to edit post page + await admin.editPost( post.id ); + + // Add the v3 block + await editor.insertBlock( { name: BLOCK_NAME } ); + + // Wait for the block fields to appear in the sidebar + await page.waitForSelector( '.acf-block-fields', { + state: 'visible', + timeout: 10000, + } ); + + // Verify that there is NO edit/preview mode toggle button + // V3 blocks should always be in preview mode + const modeToggle = page.locator( + '[data-type="scf/v3-block"] button[aria-label*="mode"]' + ); + await expect( modeToggle ).toHaveCount( 0 ); + + // Verify the block preview is visible in the canvas + const canvas = await editor.canvas; + const blockPreview = canvas.locator( + '[data-type="scf/v3-block"] .v3-block' + ); + await blockPreview.waitFor( { state: 'visible', timeout: 5000 } ); + + // Verify the placeholder title is shown (since we haven't filled the title yet) + const placeholderTitle = canvas.locator( + '[data-type="scf/v3-block"] .v3-block__title--placeholder' + ); + await expect( placeholderTitle ).toBeVisible(); + } ); + + test( 'should update preview when sidebar fields change', async ( { + page, + admin, + editor, + requestUtils, + } ) => { + // Create a new post + const post = await requestUtils.createPost( { + title: 'V3 Block Live Update Test', + status: 'draft', + } ); + + // Navigate to edit post page + await admin.editPost( post.id ); + + // Add the v3 block + await editor.insertBlock( { name: BLOCK_NAME } ); + + // Wait for the block fields to appear in the sidebar + await page.waitForSelector( '.acf-block-fields', { + state: 'visible', + timeout: 10000, + } ); + + // Get the editor canvas + const canvas = await editor.canvas; + + // Fill in the title field + const titleField = page.locator( + '.acf-field[data-name="title"] input[type="text"]' + ); + await titleField.fill( 'Featured Product' ); + await titleField.blur(); + + // Verify preview shows the title + const blockTitle = canvas.locator( + '[data-type="scf/v3-block"] .v3-block__title' + ); + await expect( blockTitle ).toContainText( 'Featured Product' ); + + // Fill in the description field + const descriptionField = page.locator( + '.acf-field[data-name="description"] textarea' + ); + await descriptionField.fill( + 'This is an amazing product description.' + ); + await descriptionField.blur(); + + // Verify preview shows the description + const blockDescription = canvas.locator( + '[data-type="scf/v3-block"] .v3-block__description' + ); + await expect( blockDescription ).toContainText( + 'This is an amazing product description.' + ); + + // Toggle the show_badge field + const badgeSwitch = page.locator( + '.acf-field[data-name="show_badge"] .acf-switch' + ); + await badgeSwitch.click(); + + // Verify badge appears in preview + const blockBadge = canvas.locator( + '[data-type="scf/v3-block"] .v3-block__badge' + ); + await expect( blockBadge ).toBeVisible(); + await expect( blockBadge ).toContainText( 'Featured' ); + + // Save the post + await page.click( '.editor-post-save-draft' ); + + // Wait for save to complete + const savedNotice = page.locator( + '.components-snackbar:has-text("Draft saved")' + ); + await expect( savedNotice ).toBeVisible( { timeout: 5000 } ); + } ); + + test( 'should validate required fields on publish', async ( { + page, + admin, + editor, + requestUtils, + } ) => { + // Create a new post + const post = await requestUtils.createPost( { + title: 'V3 Block Validation Test', + status: 'draft', + } ); + + // Navigate to edit post page + await admin.editPost( post.id ); + + // Add the v3 block + await editor.insertBlock( { name: BLOCK_NAME } ); + + // Wait for the block fields to appear in the sidebar + await page.waitForSelector( '.acf-block-fields', { + state: 'visible', + timeout: 10000, + } ); + + // Clear the title field to ensure it's empty (title is required) + const titleField = page.locator( + '.acf-field[data-name="title"] input[type="text"]' + ); + await titleField.clear(); + await titleField.blur(); + + // Try to publish to trigger full validation + const publishToggle = page.locator( + '.editor-post-publish-panel__toggle' + ); + await publishToggle.click(); + + // Click publish button + const publishButton = page.locator( + '.editor-post-publish-panel .editor-post-publish-button' + ); + await publishButton.waitFor( { state: 'visible' } ); + await publishButton.click(); + + // Wait for the error notice to appear + const errorNotice = page.locator( + '.components-notice.is-error .components-notice__content' + ); + await expect( errorNotice ).toBeVisible( { timeout: 3000 } ); + } ); + + test( 'should save v3 block data correctly', async ( { + page, + admin, + editor, + requestUtils, + } ) => { + // Create a new post + const post = await requestUtils.createPost( { + title: 'V3 Block Save Test', + status: 'draft', + } ); + + // Navigate to edit post page + await admin.editPost( post.id ); + + // Add the v3 block + await editor.insertBlock( { name: BLOCK_NAME } ); + + // Wait for the block fields to appear in the sidebar + await page.waitForSelector( '.acf-block-fields', { + state: 'visible', + timeout: 10000, + } ); + + // Get the editor canvas + const canvas = await editor.canvas; + + // Fill in all fields with blur to commit changes + const titleField = page.locator( + '.acf-field[data-name="title"] input[type="text"]' + ); + await titleField.fill( 'Saved Title' ); + await titleField.blur(); + + // Wait for preview to update with the title + const blockTitle = canvas.locator( + '[data-type="scf/v3-block"] .v3-block__title' + ); + await expect( blockTitle ).toContainText( 'Saved Title', { + timeout: 5000, + } ); + + const descriptionField = page.locator( + '.acf-field[data-name="description"] textarea' + ); + await descriptionField.fill( 'Saved description text.' ); + await descriptionField.blur(); + + // Wait for preview to update with the description + const blockDescription = canvas.locator( + '[data-type="scf/v3-block"] .v3-block__description' + ); + await expect( blockDescription ).toContainText( + 'Saved description text.', + { timeout: 5000 } + ); + + const badgeSwitch = page.locator( + '.acf-field[data-name="show_badge"] .acf-switch' + ); + await badgeSwitch.click(); + + // Wait for badge to appear in preview + const blockBadge = canvas.locator( + '[data-type="scf/v3-block"] .v3-block__badge' + ); + await expect( blockBadge ).toBeVisible( { timeout: 5000 } ); + + // Save the post + await page.click( '.editor-post-save-draft' ); + + // Wait for save to complete + const savedNotice = page.locator( + '.components-snackbar:has-text("Draft saved")' + ); + await expect( savedNotice ).toBeVisible( { timeout: 5000 } ); + + // Reload the page + await page.reload(); + + // Wait for editor to fully load + await page.waitForLoadState( 'domcontentloaded' ); + + // Get the editor canvas and select the block + const canvasAfterReload = await editor.canvas; + const blockAfterReload = canvasAfterReload.locator( + '[data-type="scf/v3-block"]' + ); + await blockAfterReload.waitFor( { state: 'visible', timeout: 10000 } ); + await blockAfterReload.click(); + + // Wait for block fields to load again + await page.waitForSelector( '.acf-block-fields', { + state: 'visible', + timeout: 10000, + } ); + + // Verify the fields retained their values + const titleFieldAfterReload = page.locator( + '.acf-field[data-name="title"] input[type="text"]' + ); + await expect( titleFieldAfterReload ).toHaveValue( 'Saved Title' ); + + const descriptionFieldAfterReload = page.locator( + '.acf-field[data-name="description"] textarea' + ); + await expect( descriptionFieldAfterReload ).toHaveValue( + 'Saved description text.' + ); + + // Verify the badge switch is on + const badgeSwitchAfterReload = page.locator( + '.acf-field[data-name="show_badge"] .acf-switch' + ); + const badgeClass = await badgeSwitchAfterReload.getAttribute( 'class' ); + expect( badgeClass ).toContain( '-on' ); + } ); +} ); diff --git a/tests/e2e/plugins/blocks/scf-v3-block/block.json b/tests/e2e/plugins/blocks/scf-v3-block/block.json new file mode 100644 index 00000000..8f8d635d --- /dev/null +++ b/tests/e2e/plugins/blocks/scf-v3-block/block.json @@ -0,0 +1,16 @@ +{ + "$schema": "https://schemas.wp.org/trunk/block.json", + "apiVersion": 3, + "name": "scf/v3-block", + "title": "SCF V3 Block", + "description": "A test block using SCF block version 3 features.", + "category": "text", + "icon": "star-filled", + "keywords": [ "v3", "test", "scf" ], + "acf": { + "blockVersion": 3, + "mode": "preview", + "renderTemplate": "template.php" + }, + "textdomain": "secure-custom-fields" +} diff --git a/tests/e2e/plugins/blocks/scf-v3-block/template.php b/tests/e2e/plugins/blocks/scf-v3-block/template.php new file mode 100644 index 00000000..b52aeea8 --- /dev/null +++ b/tests/e2e/plugins/blocks/scf-v3-block/template.php @@ -0,0 +1,36 @@ + +
+ +

+ +

Enter a title...

+ + + +

+ + + + Featured + +
diff --git a/tests/e2e/plugins/scf-test-all-field-types.php b/tests/e2e/plugins/scf-test-all-field-types.php index bbfe18ee..82c98aa5 100644 --- a/tests/e2e/plugins/scf-test-all-field-types.php +++ b/tests/e2e/plugins/scf-test-all-field-types.php @@ -8,6 +8,263 @@ * @package scf-test-plugins */ +/** + * Register field group with all testable field types. + */ +function scf_test_register_all_field_types_group() { + if ( ! function_exists( 'acf_add_local_field_group' ) ) { + return; + } + + acf_add_local_field_group( + array( + 'key' => 'group_all_field_types', + 'title' => 'All Field Types Test Group', + 'fields' => array( + // Text-based fields + array( + 'key' => 'field_test_text', + 'label' => 'Text Field', + 'name' => 'text_field', + 'type' => 'text', + ), + array( + 'key' => 'field_test_textarea', + 'label' => 'Textarea Field', + 'name' => 'textarea_field', + 'type' => 'textarea', + 'rows' => 3, + ), + array( + 'key' => 'field_test_email', + 'label' => 'Email Field', + 'name' => 'email_field', + 'type' => 'email', + ), + array( + 'key' => 'field_test_url', + 'label' => 'URL Field', + 'name' => 'url_field', + 'type' => 'url', + ), + array( + 'key' => 'field_test_password', + 'label' => 'Password Field', + 'name' => 'password_field', + 'type' => 'password', + ), + array( + 'key' => 'field_test_number', + 'label' => 'Number Field', + 'name' => 'number_field', + 'type' => 'number', + ), + array( + 'key' => 'field_test_range', + 'label' => 'Range Field', + 'name' => 'range_field', + 'type' => 'range', + 'min' => 0, + 'max' => 100, + 'default_value' => 50, + ), + + // Selection fields + array( + 'key' => 'field_test_select', + 'label' => 'Select Field', + 'name' => 'select_field', + 'type' => 'select', + 'choices' => array( + 'option_1' => 'Option 1', + 'option_2' => 'Option 2', + 'option_3' => 'Option 3', + ), + ), + array( + 'key' => 'field_test_checkbox', + 'label' => 'Checkbox Field', + 'name' => 'checkbox_field', + 'type' => 'checkbox', + 'choices' => array( + 'check_a' => 'Check A', + 'check_b' => 'Check B', + 'check_c' => 'Check C', + ), + ), + array( + 'key' => 'field_test_radio', + 'label' => 'Radio Field', + 'name' => 'radio_field', + 'type' => 'radio', + 'choices' => array( + 'radio_1' => 'Radio 1', + 'radio_2' => 'Radio 2', + 'radio_3' => 'Radio 3', + ), + ), + array( + 'key' => 'field_test_button_group', + 'label' => 'Button Group Field', + 'name' => 'button_group_field', + 'type' => 'button_group', + 'choices' => array( + 'button_1' => 'Button 1', + 'button_2' => 'Button 2', + 'button_3' => 'Button 3', + ), + ), + array( + 'key' => 'field_test_true_false', + 'label' => 'True/False Field', + 'name' => 'true_false_field', + 'type' => 'true_false', + 'ui' => 1, + ), + + // Date/time fields + array( + 'key' => 'field_test_date_picker', + 'label' => 'Date Picker Field', + 'name' => 'date_picker_field', + 'type' => 'date_picker', + 'display_format' => 'F j, Y', + 'return_format' => 'Y-m-d', + ), + array( + 'key' => 'field_test_time_picker', + 'label' => 'Time Picker Field', + 'name' => 'time_picker_field', + 'type' => 'time_picker', + 'display_format' => 'g:i a', + 'return_format' => 'H:i:s', + ), + array( + 'key' => 'field_test_date_time_picker', + 'label' => 'Date Time Picker Field', + 'name' => 'date_time_picker_field', + 'type' => 'date_time_picker', + 'display_format' => 'F j, Y g:i a', + 'return_format' => 'Y-m-d H:i:s', + ), + + // Content fields + array( + 'key' => 'field_test_wysiwyg', + 'label' => 'WYSIWYG Field', + 'name' => 'wysiwyg_field', + 'type' => 'wysiwyg', + 'tabs' => 'all', + 'toolbar' => 'full', + ), + array( + 'key' => 'field_test_color_picker', + 'label' => 'Color Picker Field', + 'name' => 'color_picker_field', + 'type' => 'color_picker', + ), + array( + 'key' => 'field_test_link', + 'label' => 'Link Field', + 'name' => 'link_field', + 'type' => 'link', + ), + + // Media field + array( + 'key' => 'field_test_image', + 'label' => 'Image Field', + 'name' => 'image_field', + 'type' => 'image', + 'return_format' => 'array', + 'preview_size' => 'thumbnail', + ), + + // Relationship fields + array( + 'key' => 'field_test_user', + 'label' => 'User Field', + 'name' => 'user_field', + 'type' => 'user', + 'return_format' => 'object', + 'multiple' => 0, + ), + array( + 'key' => 'field_test_taxonomy', + 'label' => 'Taxonomy Field', + 'name' => 'taxonomy_field', + 'type' => 'taxonomy', + 'taxonomy' => 'category', + 'field_type' => 'select', + 'return_format' => 'object', + ), + + // Container fields + array( + 'key' => 'field_test_group', + 'label' => 'Group Field', + 'name' => 'group_field', + 'type' => 'group', + 'layout' => 'block', + 'sub_fields' => array( + array( + 'key' => 'field_test_group_text', + 'label' => 'Group Text', + 'name' => 'group_text', + 'type' => 'text', + ), + array( + 'key' => 'field_test_group_number', + 'label' => 'Group Number', + 'name' => 'group_number', + 'type' => 'number', + ), + ), + ), + array( + 'key' => 'field_test_repeater', + 'label' => 'Repeater Field', + 'name' => 'repeater_field', + 'type' => 'repeater', + 'layout' => 'table', + 'min' => 0, + 'max' => 5, + 'sub_fields' => array( + array( + 'key' => 'field_test_repeater_text', + 'label' => 'Repeater Text', + 'name' => 'repeater_text', + 'type' => 'text', + ), + array( + 'key' => 'field_test_repeater_number', + 'label' => 'Repeater Number', + 'name' => 'repeater_number', + 'type' => 'number', + ), + ), + ), + ), + 'location' => array( + array( + array( + 'param' => 'post_type', + 'operator' => '==', + 'value' => 'post', + ), + ), + ), + 'menu_order' => 0, + 'position' => 'normal', + 'style' => 'default', + 'label_placement' => 'top', + 'instruction_placement' => 'label', + 'active' => true, + ) + ); +} +add_action( 'acf/init', 'scf_test_register_all_field_types_group' ); + /** * Output all SCF field values on post content. * diff --git a/tests/e2e/plugins/scf-test-v3-block.php b/tests/e2e/plugins/scf-test-v3-block.php new file mode 100644 index 00000000..895615d1 --- /dev/null +++ b/tests/e2e/plugins/scf-test-v3-block.php @@ -0,0 +1,85 @@ + 'group_v3_block_fields', + 'title' => 'V3 Block Fields', + 'fields' => array( + array( + 'key' => 'field_v3_title', + 'label' => 'Title', + 'name' => 'title', + 'type' => 'text', + 'required' => 1, + 'placeholder' => 'Enter a title...', + ), + array( + 'key' => 'field_v3_description', + 'label' => 'Description', + 'name' => 'description', + 'type' => 'textarea', + 'placeholder' => 'Enter a description...', + 'rows' => 3, + ), + array( + 'key' => 'field_v3_show_badge', + 'label' => 'Show Badge', + 'name' => 'show_badge', + 'type' => 'true_false', + 'default_value' => 0, + 'ui' => 1, + ), + ), + 'location' => array( + array( + array( + 'param' => 'block', + 'operator' => '==', + 'value' => 'scf/v3-block', + ), + ), + ), + 'menu_order' => 0, + 'position' => 'normal', + 'style' => 'default', + 'label_placement' => 'top', + 'instruction_placement' => 'label', + 'hide_on_screen' => '', + 'active' => true, + 'description' => 'Fields for testing V3 block features', + 'show_in_rest' => 0, + ) + ); +} +add_action( 'acf/init', 'scf_test_register_v3_block_fields' );