Skip to content

Commit 08bb841

Browse files
Tsvetan StoychevTsvetan Stoychev
authored andcommitted
Disable delay until wait after onload is enabled
1 parent 6805b09 commit 08bb841

4 files changed

Lines changed: 167 additions & 5 deletions

File tree

‎plugins/basicrum/assets/js/admin/settings.js‎

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33

44
document.addEventListener( 'DOMContentLoaded', function() {
55
var enabled = document.getElementById( 'basicrum_enabled' );
6+
var waitAfterOnload = document.getElementById( 'basicrum_wait_after_onload' );
7+
var delay = document.getElementById( 'basicrum_delay_ms' );
68
var form = enabled ? enabled.closest( 'form' ) : null;
79
var fieldIds = [ 'basicrum_beacon_url', 'basicrum_brum_site_id' ];
810
var requiredFields = fieldIds.map( function( fieldId ) {
@@ -62,6 +64,19 @@
6264
preservedValues.forEach( function( field ) {
6365
field.disabled = isEnabled;
6466
} );
67+
68+
syncDelayAvailability();
69+
}
70+
71+
function syncDelayAvailability() {
72+
if ( ! waitAfterOnload || ! delay ) {
73+
return;
74+
}
75+
76+
var isDelayEnabled = enabled.checked && waitAfterOnload.checked;
77+
78+
delay.disabled = ! isDelayEnabled;
79+
delay.setAttribute( 'aria-disabled', isDelayEnabled ? 'false' : 'true' );
6580
}
6681

6782
syncAvailability();
@@ -88,8 +103,16 @@
88103
} );
89104
} );
90105

106+
if ( waitAfterOnload ) {
107+
waitAfterOnload.addEventListener( 'change', syncDelayAvailability );
108+
}
109+
91110
form.addEventListener( 'submit', function() {
92111
if ( enabled.checked ) {
112+
if ( waitAfterOnload && delay && ! waitAfterOnload.checked ) {
113+
delay.disabled = false;
114+
}
115+
93116
return;
94117
}
95118

‎plugins/basicrum/src/Admin/Settings/Page.php‎

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,18 +71,39 @@ public function enqueue_admin_assets( $hook_suffix ) {
7171
self::HANDLE_SETTINGS,
7272
Helpers::get_asset_url( 'js/admin/settings.js' ),
7373
array(),
74-
BASICRUM_VERSION,
74+
$this->get_admin_asset_version( 'js/admin/settings.js' ),
7575
true
7676
);
7777

7878
wp_enqueue_style(
7979
self::HANDLE_SETTINGS_STYLE,
8080
Helpers::get_asset_url( 'css/admin/settings.css' ),
8181
array(),
82-
BASICRUM_VERSION
82+
$this->get_admin_asset_version( 'css/admin/settings.css' )
8383
);
8484
}
8585

86+
/**
87+
* Get a cache-busting version for an admin asset.
88+
*
89+
* The plugin version changes for releases. The file modification time also
90+
* makes local and development changes take effect without a stale browser
91+
* cache continuing to run an earlier settings script.
92+
*
93+
* @param string $asset Relative asset path.
94+
* @return string Asset version.
95+
*/
96+
private function get_admin_asset_version( $asset ) {
97+
$asset_path = Helpers::get_asset_path( $asset );
98+
$modified = is_readable( $asset_path ) ? filemtime( $asset_path ) : false;
99+
100+
if ( false === $modified ) {
101+
return BASICRUM_VERSION;
102+
}
103+
104+
return BASICRUM_VERSION . '.' . $modified;
105+
}
106+
86107
/**
87108
* Add the top-level Basicrum menu page.
88109
*
@@ -229,7 +250,15 @@ private function get_required_field_row_class( $settings, $setting_key ) {
229250
* @return bool Whether the control should be disabled.
230251
*/
231252
private function is_field_disabled( $setting_key, $settings ) {
232-
return 'enabled' !== $setting_key && '1' !== $settings['enabled'];
253+
if ( 'enabled' === $setting_key ) {
254+
return false;
255+
}
256+
257+
if ( '1' !== $settings['enabled'] ) {
258+
return true;
259+
}
260+
261+
return 'delay_ms' === $setting_key && '1' !== $settings['wait_after_onload'];
233262
}
234263

235264
/**

‎plugins/basicrum/tests/unit/SettingsPageTest.php‎

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,48 @@ public function required_field_provider() {
167167
);
168168
}
169169

170+
/**
171+
* Test the delay field is available only when monitoring and Wait After Onload are active.
172+
*
173+
* @dataProvider delay_field_availability_provider
174+
*
175+
* @param string $enabled Enabled setting value.
176+
* @param string $wait_after_onload Wait After Onload setting value.
177+
* @param bool $expect_disabled Whether the delay field should be disabled.
178+
*/
179+
public function test_delay_field_depends_on_wait_after_onload( $enabled, $wait_after_onload, $expect_disabled ) {
180+
$this->set_settings(
181+
array(
182+
'enabled' => $enabled,
183+
'wait_after_onload' => $wait_after_onload,
184+
'delay_ms' => 500,
185+
)
186+
);
187+
188+
$page = new Page();
189+
190+
ob_start();
191+
$page->render_number_field( array( 'id' => 'delay_ms' ) );
192+
$html = ob_get_clean();
193+
194+
$this->assertStringContainsString( 'aria-disabled="' . ( $expect_disabled ? 'true' : 'false' ) . '"', $html );
195+
$this->assertSame( $expect_disabled, false !== strpos( $html, 'disabled="disabled"' ) );
196+
$this->assertSame( $expect_disabled, false !== strpos( $html, 'basicrum-disabled-setting-value' ) );
197+
}
198+
199+
/**
200+
* Provide delay field availability states.
201+
*
202+
* @return array[] Test cases.
203+
*/
204+
public function delay_field_availability_provider() {
205+
return array(
206+
'monitoring disabled' => array( '0', '1', true ),
207+
'wait after onload disabled' => array( '1', '0', true ),
208+
'both settings enabled' => array( '1', '1', false ),
209+
);
210+
}
211+
170212
/**
171213
* Test the privacy section exposes query protection and real loading behaviors.
172214
*/
@@ -299,6 +341,9 @@ public function test_enable_checkbox_remains_interactive_when_monitoring_is_off(
299341
* Test the conditional settings behavior is loaded on the Basicrum page.
300342
*/
301343
public function test_settings_script_is_enqueued_on_basicrum_page() {
344+
$script_version = BASICRUM_VERSION . '.' . filemtime( \Basicrum\WP\Helpers::get_asset_path( 'js/admin/settings.js' ) );
345+
$style_version = BASICRUM_VERSION . '.' . filemtime( \Basicrum\WP\Helpers::get_asset_path( 'css/admin/settings.css' ) );
346+
302347
Functions\when( 'plugins_url' )->alias(
303348
function( $path ) {
304349
return 'https://example.com/wp-content/plugins/basicrum/' . $path;
@@ -310,7 +355,7 @@ function( $path ) {
310355
'basicrum-admin-settings',
311356
'https://example.com/wp-content/plugins/basicrum/assets/js/admin/settings.js',
312357
array(),
313-
BASICRUM_VERSION,
358+
$script_version,
314359
true
315360
);
316361
Functions\expect( 'wp_enqueue_style' )
@@ -319,7 +364,7 @@ function( $path ) {
319364
'basicrum-admin-settings-style',
320365
'https://example.com/wp-content/plugins/basicrum/assets/css/admin/settings.css',
321366
array(),
322-
BASICRUM_VERSION
367+
$style_version
323368
);
324369

325370
$page = new Page();
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
const fs = require( 'node:fs' );
2+
const path = require( 'node:path' );
3+
const { test, expect } = require( '@playwright/test' );
4+
5+
const SETTINGS_SCRIPT = fs.readFileSync(
6+
path.join(
7+
__dirname,
8+
'../../plugins/basicrum/assets/js/admin/settings.js'
9+
),
10+
'utf8'
11+
);
12+
13+
/**
14+
* Load the settings behavior into a representative settings form.
15+
*
16+
* @param {import('@playwright/test').Page} page Playwright page.
17+
* @return {Promise<void>} Completion promise.
18+
*/
19+
async function loadSettingsForm( page ) {
20+
await page.setContent( `
21+
<form id="basicrum-settings-form">
22+
<label><input id="basicrum_enabled" name="basicrum_settings[enabled]" type="checkbox" value="1" checked> Enable Basicrum</label>
23+
<input id="basicrum_beacon_url" name="basicrum_settings[beacon_url]" value="https://collector.example.test/beacon">
24+
<input id="basicrum_brum_site_id" name="basicrum_settings[brum_site_id]" value="550e8400-e29b-41d4-a716-446655440000">
25+
<label><input id="basicrum_wait_after_onload" name="basicrum_settings[wait_after_onload]" type="checkbox" value="1"> Wait After Onload</label>
26+
<input id="basicrum_delay_ms" name="basicrum_settings[delay_ms]" type="number" value="750" aria-disabled="true" disabled>
27+
<input class="basicrum-disabled-setting-value" name="basicrum_settings[delay_ms]" type="hidden" value="750">
28+
</form>
29+
` );
30+
31+
await page.addScriptTag( { content: SETTINGS_SCRIPT } );
32+
await page.evaluate( () => document.dispatchEvent( new Event( 'DOMContentLoaded' ) ) );
33+
}
34+
35+
test( 'enables Delay only when Wait After Onload is active', async ( { page } ) => {
36+
await loadSettingsForm( page );
37+
38+
const waitAfterOnload = page.locator( '#basicrum_wait_after_onload' );
39+
const delay = page.locator( '#basicrum_delay_ms' );
40+
41+
await expect( delay ).toBeDisabled();
42+
await expect( delay ).toHaveAttribute( 'aria-disabled', 'true' );
43+
44+
await waitAfterOnload.check();
45+
await expect( delay ).toBeEnabled();
46+
await expect( delay ).toHaveAttribute( 'aria-disabled', 'false' );
47+
48+
await waitAfterOnload.uncheck();
49+
await expect( delay ).toBeDisabled();
50+
await expect( delay ).toHaveAttribute( 'aria-disabled', 'true' );
51+
} );
52+
53+
test( 'preserves Delay when Wait After Onload is inactive and the form is submitted', async ( { page } ) => {
54+
await loadSettingsForm( page );
55+
56+
await page.locator( '#basicrum-settings-form' ).evaluate( ( form ) => {
57+
form.addEventListener( 'submit', ( event ) => {
58+
event.preventDefault();
59+
window.basicrumSubmittedDelay = new FormData( form ).get( 'basicrum_settings[delay_ms]' );
60+
}, { once: true } );
61+
form.requestSubmit();
62+
} );
63+
64+
expect( await page.evaluate( () => window.basicrumSubmittedDelay ) ).toBe( '750' );
65+
} );

0 commit comments

Comments
 (0)