Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 66 additions & 1 deletion includes/forms/form-user.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,71 @@ function admin_enqueue_scripts() {

// enqueue
acf_enqueue_scripts();

// Fix SCF field layout on user profile/edit screens.
if ( ! acf_is_screen( array( 'profile', 'user-edit', 'profile-network', 'user-edit-network' ) ) ) {
return;
}

wp_add_inline_style( 'acf-input', $this->get_user_form_layout_css() );
}

/**
* Returns custom CSS to improve SCF field layout on user profile/edit screens.
*
* @since ACF 6.8.2
*
* @return string
*/
public function get_user_form_layout_css() {
return <<<'CSS'
table.form-table tr.acf-field > td.acf-label {
width: 200px;
vertical-align: top;
padding-top: 14px;
}

table.form-table tr.acf-field > td.acf-input {
vertical-align: top;
}

table.form-table tr.acf-field > td.acf-input .acf-input-wrap input[type="text"],
table.form-table tr.acf-field > td.acf-input .acf-input-wrap input[type="password"],
table.form-table tr.acf-field > td.acf-input .acf-input-wrap input[type="email"],
table.form-table tr.acf-field > td.acf-input .acf-input-wrap input[type="number"],
table.form-table tr.acf-field > td.acf-input .acf-input-wrap input[type="url"],
table.form-table tr.acf-field > td.acf-input .acf-input-wrap input[type="search"],
table.form-table tr.acf-field > td.acf-input .acf-input-wrap input[type="tel"],
table.form-table tr.acf-field > td.acf-input textarea {
width: 100%;
max-width: 25em;
}

table.form-table tr.acf-field > td.acf-input .select2-container {
width: 100% !important;
max-width: 25em;
}

@media screen and (max-width: 782px) {
table.form-table tr.acf-field > td.acf-label,
table.form-table tr.acf-field > td.acf-input {
display: block;
width: auto;
}

table.form-table tr.acf-field > td.acf-input .acf-input-wrap input[type="text"],
table.form-table tr.acf-field > td.acf-input .acf-input-wrap input[type="password"],
table.form-table tr.acf-field > td.acf-input .acf-input-wrap input[type="email"],
table.form-table tr.acf-field > td.acf-input .acf-input-wrap input[type="number"],
table.form-table tr.acf-field > td.acf-input .acf-input-wrap input[type="url"],
table.form-table tr.acf-field > td.acf-input .acf-input-wrap input[type="search"],
table.form-table tr.acf-field > td.acf-input .acf-input-wrap input[type="tel"],
table.form-table tr.acf-field > td.acf-input textarea,
table.form-table tr.acf-field > td.acf-input .select2-container {
max-width: 100%;
}
}
CSS;
}


Expand Down Expand Up @@ -358,4 +423,4 @@ function filter_pre_load_value( $null, $post_id, $field ) {
acf_new_instance( 'ACF_Form_User' );
endif; // class_exists check

?>
?>
27 changes: 21 additions & 6 deletions tests/e2e/field-helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,10 @@
*/
async function uploadImageViaModal( page, imagePath ) {
// Wait for media modal to open
await page.waitForSelector( '.media-modal', { state: 'visible' } );
await page.waitForSelector( '.media-modal', {

Check failure on line 144 in tests/e2e/field-helpers.js

View workflow job for this annotation

GitHub Actions / E2E - Node 22 / WP trunk / Shard 3/4

[chromium] › tests/e2e/field-type-image.spec.ts:106:2 › Field Type > Image › should allow removing an image

2) [chromium] › tests/e2e/field-type-image.spec.ts:106:2 › Field Type > Image › should allow removing an image Retry #2 ─────────────────────────────────────────────────────────────────────────────────────── TimeoutError: page.waitForSelector: Timeout 20000ms exceeded. Call log: - waiting for locator('.media-modal') to be visible at field-helpers.js:144 142 | async function uploadImageViaModal( page, imagePath ) { 143 | // Wait for media modal to open > 144 | await page.waitForSelector( '.media-modal', { | ^ 145 | state: 'visible', 146 | timeout: 20000, 147 | } ); at uploadImageViaModal (/home/runner/work/secure-custom-fields/secure-custom-fields/tests/e2e/field-helpers.js:144:13) at /home/runner/work/secure-custom-fields/secure-custom-fields/tests/e2e/field-type-image.spec.ts:151:9

Check failure on line 144 in tests/e2e/field-helpers.js

View workflow job for this annotation

GitHub Actions / E2E - Node 22 / WP trunk / Shard 3/4

[chromium] › tests/e2e/field-type-image.spec.ts:106:2 › Field Type > Image › should allow removing an image

2) [chromium] › tests/e2e/field-type-image.spec.ts:106:2 › Field Type > Image › should allow removing an image Retry #1 ─────────────────────────────────────────────────────────────────────────────────────── TimeoutError: page.waitForSelector: Timeout 20000ms exceeded. Call log: - waiting for locator('.media-modal') to be visible at field-helpers.js:144 142 | async function uploadImageViaModal( page, imagePath ) { 143 | // Wait for media modal to open > 144 | await page.waitForSelector( '.media-modal', { | ^ 145 | state: 'visible', 146 | timeout: 20000, 147 | } ); at uploadImageViaModal (/home/runner/work/secure-custom-fields/secure-custom-fields/tests/e2e/field-helpers.js:144:13) at /home/runner/work/secure-custom-fields/secure-custom-fields/tests/e2e/field-type-image.spec.ts:151:9

Check failure on line 144 in tests/e2e/field-helpers.js

View workflow job for this annotation

GitHub Actions / E2E - Node 22 / WP trunk / Shard 3/4

[chromium] › tests/e2e/field-type-image.spec.ts:106:2 › Field Type > Image › should allow removing an image

2) [chromium] › tests/e2e/field-type-image.spec.ts:106:2 › Field Type > Image › should allow removing an image TimeoutError: page.waitForSelector: Timeout 20000ms exceeded. Call log: - waiting for locator('.media-modal') to be visible at field-helpers.js:144 142 | async function uploadImageViaModal( page, imagePath ) { 143 | // Wait for media modal to open > 144 | await page.waitForSelector( '.media-modal', { | ^ 145 | state: 'visible', 146 | timeout: 20000, 147 | } ); at uploadImageViaModal (/home/runner/work/secure-custom-fields/secure-custom-fields/tests/e2e/field-helpers.js:144:13) at /home/runner/work/secure-custom-fields/secure-custom-fields/tests/e2e/field-type-image.spec.ts:151:9

Check failure on line 144 in tests/e2e/field-helpers.js

View workflow job for this annotation

GitHub Actions / E2E - Node 22 / WP trunk / Shard 3/4

[chromium] › tests/e2e/field-type-image.spec.ts:36:2 › Field Type > Image › should create an image field and upload an image

1) [chromium] › tests/e2e/field-type-image.spec.ts:36:2 › Field Type > Image › should create an image field and upload an image Retry #2 ─────────────────────────────────────────────────────────────────────────────────────── TimeoutError: page.waitForSelector: Timeout 20000ms exceeded. Call log: - waiting for locator('.media-modal') to be visible at field-helpers.js:144 142 | async function uploadImageViaModal( page, imagePath ) { 143 | // Wait for media modal to open > 144 | await page.waitForSelector( '.media-modal', { | ^ 145 | state: 'visible', 146 | timeout: 20000, 147 | } ); at uploadImageViaModal (/home/runner/work/secure-custom-fields/secure-custom-fields/tests/e2e/field-helpers.js:144:13) at /home/runner/work/secure-custom-fields/secure-custom-fields/tests/e2e/field-type-image.spec.ts:85:9

Check failure on line 144 in tests/e2e/field-helpers.js

View workflow job for this annotation

GitHub Actions / E2E - Node 22 / WP trunk / Shard 3/4

[chromium] › tests/e2e/field-type-image.spec.ts:36:2 › Field Type > Image › should create an image field and upload an image

1) [chromium] › tests/e2e/field-type-image.spec.ts:36:2 › Field Type > Image › should create an image field and upload an image Retry #1 ─────────────────────────────────────────────────────────────────────────────────────── TimeoutError: page.waitForSelector: Timeout 20000ms exceeded. Call log: - waiting for locator('.media-modal') to be visible at field-helpers.js:144 142 | async function uploadImageViaModal( page, imagePath ) { 143 | // Wait for media modal to open > 144 | await page.waitForSelector( '.media-modal', { | ^ 145 | state: 'visible', 146 | timeout: 20000, 147 | } ); at uploadImageViaModal (/home/runner/work/secure-custom-fields/secure-custom-fields/tests/e2e/field-helpers.js:144:13) at /home/runner/work/secure-custom-fields/secure-custom-fields/tests/e2e/field-type-image.spec.ts:85:9

Check failure on line 144 in tests/e2e/field-helpers.js

View workflow job for this annotation

GitHub Actions / E2E - Node 22 / WP trunk / Shard 3/4

[chromium] › tests/e2e/field-type-image.spec.ts:36:2 › Field Type > Image › should create an image field and upload an image

1) [chromium] › tests/e2e/field-type-image.spec.ts:36:2 › Field Type > Image › should create an image field and upload an image TimeoutError: page.waitForSelector: Timeout 20000ms exceeded. Call log: - waiting for locator('.media-modal') to be visible at field-helpers.js:144 142 | async function uploadImageViaModal( page, imagePath ) { 143 | // Wait for media modal to open > 144 | await page.waitForSelector( '.media-modal', { | ^ 145 | state: 'visible', 146 | timeout: 20000, 147 | } ); at uploadImageViaModal (/home/runner/work/secure-custom-fields/secure-custom-fields/tests/e2e/field-helpers.js:144:13) at /home/runner/work/secure-custom-fields/secure-custom-fields/tests/e2e/field-type-image.spec.ts:85:9
state: 'visible',
timeout: 20000,
} );

// Click "Upload files" tab if not already there
const uploadTab = page.locator( '.media-modal #menu-item-upload' );
Expand All @@ -153,17 +156,29 @@
const fileInput = page.locator( '.media-modal input[type="file"]' );
await fileInput.setInputFiles( imagePath );

// Wait for upload to complete
await page.waitForSelector( '.media-modal .attachment.selected', {
state: 'visible',
timeout: 15000,
} );
// Wait for upload to complete and ensure an attachment is selected.
try {
await page.waitForSelector( '.media-modal .attachment.selected', {
state: 'visible',
timeout: 30000,
} );
} catch {
await page.waitForSelector( '.media-modal .attachments .attachment', {
state: 'visible',
timeout: 30000,
} );
await page.locator( '.media-modal .attachments .attachment' ).first().click();
await page.waitForSelector( '.media-modal .attachment.selected', {
state: 'visible',
timeout: 10000,
} );
}

// Click "Select" button
const selectButton = page.locator(
'.media-modal .media-toolbar-primary .media-button-select'
);
await selectButton.click();

Check failure on line 181 in tests/e2e/field-helpers.js

View workflow job for this annotation

GitHub Actions / E2E - Node 22 / WP trunk / Shard 2/4

[chromium] › tests/e2e/all-field-types.spec.ts:59:2 › All Field Types › should save and display all field types correctly

1) [chromium] › tests/e2e/all-field-types.spec.ts:59:2 › All Field Types › should save and display all field types correctly Retry #2 ─────────────────────────────────────────────────────────────────────────────────────── TimeoutError: locator.click: Timeout 10000ms exceeded. Call log: - waiting for locator('.media-modal .media-toolbar-primary .media-button-select') - locator resolved to <button type="button" disabled="disabled" class="button media-button button-primary button-large media-button-select">Select</button> - attempting click action 2 × waiting for element to be visible, enabled and stable - element is not enabled - retrying click action - waiting 20ms 2 × waiting for element to be visible, enabled and stable - element is not enabled - retrying click action - waiting 100ms 19 × waiting for element to be visible, enabled and stable - element is not enabled - retrying click action - waiting 500ms at field-helpers.js:181 179 | '.media-modal .media-toolbar-primary .media-button-select' 180 | ); > 181 | await selectButton.click(); | ^ 182 | 183 | // Wait for modal to close 184 | await page.waitForSelector( '.media-modal', { state: 'hidden' } ); at uploadImageViaModal (/home/runner/work/secure-custom-fields/secure-custom-fields/tests/e2e/field-helpers.js:181:21) at /home/runner/work/secure-custom-fields/secure-custom-fields/tests/e2e/all-field-types.spec.ts:232:3

Check failure on line 181 in tests/e2e/field-helpers.js

View workflow job for this annotation

GitHub Actions / E2E - Node 22 / WP trunk / Shard 2/4

[chromium] › tests/e2e/all-field-types.spec.ts:59:2 › All Field Types › should save and display all field types correctly

1) [chromium] › tests/e2e/all-field-types.spec.ts:59:2 › All Field Types › should save and display all field types correctly Retry #1 ─────────────────────────────────────────────────────────────────────────────────────── TimeoutError: locator.click: Timeout 10000ms exceeded. Call log: - waiting for locator('.media-modal .media-toolbar-primary .media-button-select') - locator resolved to <button type="button" disabled="disabled" class="button media-button button-primary button-large media-button-select">Select</button> - attempting click action 2 × waiting for element to be visible, enabled and stable - element is not enabled - retrying click action - waiting 20ms 2 × waiting for element to be visible, enabled and stable - element is not enabled - retrying click action - waiting 100ms 19 × waiting for element to be visible, enabled and stable - element is not enabled - retrying click action - waiting 500ms at field-helpers.js:181 179 | '.media-modal .media-toolbar-primary .media-button-select' 180 | ); > 181 | await selectButton.click(); | ^ 182 | 183 | // Wait for modal to close 184 | await page.waitForSelector( '.media-modal', { state: 'hidden' } ); at uploadImageViaModal (/home/runner/work/secure-custom-fields/secure-custom-fields/tests/e2e/field-helpers.js:181:21) at /home/runner/work/secure-custom-fields/secure-custom-fields/tests/e2e/all-field-types.spec.ts:232:3

Check failure on line 181 in tests/e2e/field-helpers.js

View workflow job for this annotation

GitHub Actions / E2E - Node 22 / WP trunk / Shard 2/4

[chromium] › tests/e2e/all-field-types.spec.ts:59:2 › All Field Types › should save and display all field types correctly

1) [chromium] › tests/e2e/all-field-types.spec.ts:59:2 › All Field Types › should save and display all field types correctly TimeoutError: locator.click: Timeout 10000ms exceeded. Call log: - waiting for locator('.media-modal .media-toolbar-primary .media-button-select') - locator resolved to <button type="button" disabled="disabled" class="button media-button button-primary button-large media-button-select">Select</button> - attempting click action 2 × waiting for element to be visible, enabled and stable - element is not enabled - retrying click action - waiting 20ms 2 × waiting for element to be visible, enabled and stable - element is not enabled - retrying click action - waiting 100ms 19 × waiting for element to be visible, enabled and stable - element is not enabled - retrying click action - waiting 500ms at field-helpers.js:181 179 | '.media-modal .media-toolbar-primary .media-button-select' 180 | ); > 181 | await selectButton.click(); | ^ 182 | 183 | // Wait for modal to close 184 | await page.waitForSelector( '.media-modal', { state: 'hidden' } ); at uploadImageViaModal (/home/runner/work/secure-custom-fields/secure-custom-fields/tests/e2e/field-helpers.js:181:21) at /home/runner/work/secure-custom-fields/secure-custom-fields/tests/e2e/all-field-types.spec.ts:232:3

// Wait for modal to close
await page.waitForSelector( '.media-modal', { state: 'hidden' } );
Expand Down
53 changes: 3 additions & 50 deletions tests/e2e/field-type-image.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const {
PLUGIN_SLUG,
deleteFieldGroups,
waitForMetaBoxes,
uploadImageViaModal,
} = require( './field-helpers' );
const path = require( 'path' );

Expand Down Expand Up @@ -81,34 +82,7 @@ test.describe( 'Field Type > Image', () => {
'.acf-field[data-name="test_image"] .acf-image-uploader[data-uploader="wp"] .acf-button-edit, .acf-field[data-name="test_image"] .acf-image-uploader a[data-name="add"]'
);
await addImageButton.click();

// Wait for media modal
await page.waitForSelector( '.media-modal', { state: 'visible' } );

// Click "Upload files" tab
const uploadTab = page.locator( '.media-modal #menu-item-upload' );
if ( await uploadTab.isVisible() ) {
await uploadTab.click();
}

// Upload the file
const fileInput = page.locator( '.media-modal input[type="file"]' );
await fileInput.setInputFiles( TEST_IMAGE_PATH );

// Wait for upload to complete
await page.waitForSelector( '.media-modal .attachment.selected', {
state: 'visible',
timeout: 30000,
} );

// Click "Select" button
const selectButton = page.locator(
'.media-modal .media-toolbar-primary .media-button-select'
);
await selectButton.click();

// Wait for modal to close
await page.waitForSelector( '.media-modal', { state: 'hidden' } );
await uploadImageViaModal( page, TEST_IMAGE_PATH );

// Verify image is displayed in the field
const imagePreview = page.locator(
Expand Down Expand Up @@ -174,28 +148,7 @@ test.describe( 'Field Type > Image', () => {
'.acf-field[data-name="removable_image"] .acf-image-uploader a[data-name="add"]'
);
await addImageButton.click();

await page.waitForSelector( '.media-modal', { state: 'visible' } );

const uploadTab = page.locator( '.media-modal #menu-item-upload' );
if ( await uploadTab.isVisible() ) {
await uploadTab.click();
}

const fileInput = page.locator( '.media-modal input[type="file"]' );
await fileInput.setInputFiles( TEST_IMAGE_PATH );

await page.waitForSelector( '.media-modal .attachment.selected', {
state: 'visible',
timeout: 30000,
} );

const selectButton = page.locator(
'.media-modal .media-toolbar-primary .media-button-select'
);
await selectButton.click();

await page.waitForSelector( '.media-modal', { state: 'hidden' } );
await uploadImageViaModal( page, TEST_IMAGE_PATH );

// Verify image is there
const imagePreview = page.locator(
Expand Down
25 changes: 25 additions & 0 deletions tests/php/includes/forms/test-form-user.php
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,31 @@ function () use ( &$enqueue_called ) {
$this->assertFalse( $enqueue_called, 'acf_enqueue_scripts should not be called when not on user screen' );
}

/**
* Test user form layout CSS includes expected rules.
*/
public function test_get_user_form_layout_css_contains_expected_rules() {
$form_user = new ACF_Form_User();
$css = $form_user->get_user_form_layout_css();

$this->assertIsString( $css, 'CSS should be a string' );
$this->assertStringContainsString(
'table.form-table tr.acf-field > td.acf-label',
$css,
'CSS should target ACF labels in user form table rows'
);
$this->assertStringContainsString(
'input[type="text"]',
$css,
'CSS should target text-like input fields'
);
$this->assertStringContainsString(
'@media screen and (max-width: 782px)',
$css,
'CSS should include responsive rules for mobile viewports'
);
}

/**
* Test render_edit renders nothing without field groups.
*/
Expand Down
Loading