Add remote logging tool to beta tester (#50425)
* Add remote logging beta tester tool * chore: Update log method return type to Promise<boolean> * Update pnpm-lock.yaml * Reformat * Check window.wcSettings?.isRemoteLoggingEnabled * Add changelogs * Fix test * Update toggle_remote_logging * Fix toggle_remote_logging * Improve message * Fix lint
This commit is contained in:
parent
e4bb2c2317
commit
450a4ce3bb
|
@ -75,7 +75,7 @@ addFilter(
|
||||||
### API Reference
|
### API Reference
|
||||||
|
|
||||||
- `init(config: RemoteLoggerConfig): void`: Initializes the remote logger with the given configuration.
|
- `init(config: RemoteLoggerConfig): void`: Initializes the remote logger with the given configuration.
|
||||||
- `log(severity: LogSeverity, message: string, extraData?: object): Promise<void>`: Logs a message with the specified severity and optional extra data.
|
- `log(severity: LogSeverity, message: string, extraData?: object): Promise<boolean>`: Logs a message with the specified severity and optional extra data.
|
||||||
- `captureException(error: Error, extraData?: object): void`: Captures an error and sends it to the remote API.
|
- `captureException(error: Error, extraData?: object): void`: Captures an error and sends it to the remote API.
|
||||||
|
|
||||||
For more detailed information about types and interfaces, refer to the source code and inline documentation.
|
For more detailed information about types and interfaces, refer to the source code and inline documentation.
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
Significance: patch
|
||||||
|
Type: tweak
|
||||||
|
|
||||||
|
Tweak logic for adding remote logging tool in beta tester
|
|
@ -69,10 +69,10 @@ export class RemoteLogger {
|
||||||
severity: Exclude< LogData[ 'severity' ], undefined >,
|
severity: Exclude< LogData[ 'severity' ], undefined >,
|
||||||
message: string,
|
message: string,
|
||||||
extraData?: Partial< Exclude< LogData, 'message' | 'severity' > >
|
extraData?: Partial< Exclude< LogData, 'message' | 'severity' > >
|
||||||
) {
|
): Promise< boolean > {
|
||||||
if ( ! message ) {
|
if ( ! message ) {
|
||||||
debug( 'Empty message' );
|
debug( 'Empty message' );
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const logData: LogData = mergeLogData( DEFAULT_LOG_DATA, {
|
const logData: LogData = mergeLogData( DEFAULT_LOG_DATA, {
|
||||||
|
@ -82,7 +82,7 @@ export class RemoteLogger {
|
||||||
} );
|
} );
|
||||||
|
|
||||||
debug( 'Logging:', logData );
|
debug( 'Logging:', logData );
|
||||||
await this.sendLog( logData );
|
return await this.sendLog( logData );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -144,10 +144,10 @@ export class RemoteLogger {
|
||||||
*
|
*
|
||||||
* @param logData - The log data to be sent.
|
* @param logData - The log data to be sent.
|
||||||
*/
|
*/
|
||||||
private async sendLog( logData: LogData ): Promise< void > {
|
private async sendLog( logData: LogData ): Promise< boolean > {
|
||||||
if ( isDevelopmentEnvironment ) {
|
if ( isDevelopmentEnvironment ) {
|
||||||
debug( 'Skipping send log in development environment' );
|
debug( 'Skipping send log in development environment' );
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const body = new window.FormData();
|
const body = new window.FormData();
|
||||||
|
@ -166,13 +166,19 @@ export class RemoteLogger {
|
||||||
'https://public-api.wordpress.com/rest/v1.1/logstash'
|
'https://public-api.wordpress.com/rest/v1.1/logstash'
|
||||||
) as string;
|
) as string;
|
||||||
|
|
||||||
await window.fetch( endpoint, {
|
const response = await window.fetch( endpoint, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
body,
|
body,
|
||||||
} );
|
} );
|
||||||
|
if ( ! response.ok ) {
|
||||||
|
throw new Error( `response body: ${ response.body }` );
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
} catch ( error ) {
|
} catch ( error ) {
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
console.error( 'Failed to send log to API:', error );
|
console.error( 'Failed to send log to API:', error );
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -368,13 +374,13 @@ let logger: RemoteLogger | null = null;
|
||||||
*
|
*
|
||||||
* @return {boolean} - Returns true if remote logging is enabled and the logger is initialized, otherwise false.
|
* @return {boolean} - Returns true if remote logging is enabled and the logger is initialized, otherwise false.
|
||||||
*/
|
*/
|
||||||
function canLog(): boolean {
|
function canLog( _logger: RemoteLogger | null ): _logger is RemoteLogger {
|
||||||
if ( ! getSetting( 'isRemoteLoggingEnabled', false ) ) {
|
if ( ! window.wcSettings?.isRemoteLoggingEnabled ) {
|
||||||
debug( 'Remote logging is disabled.' );
|
debug( 'Remote logging is disabled.' );
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! logger ) {
|
if ( ! _logger ) {
|
||||||
warnLog( 'RemoteLogger is not initialized. Call init() first.' );
|
warnLog( 'RemoteLogger is not initialized. Call init() first.' );
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -390,7 +396,7 @@ function canLog(): boolean {
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
export function init( config: RemoteLoggerConfig ) {
|
export function init( config: RemoteLoggerConfig ) {
|
||||||
if ( ! getSetting( 'isRemoteLoggingEnabled', false ) ) {
|
if ( ! window.wcSettings?.isRemoteLoggingEnabled ) {
|
||||||
debug( 'Remote logging is disabled.' );
|
debug( 'Remote logging is disabled.' );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -424,15 +430,16 @@ export async function log(
|
||||||
severity: Exclude< LogData[ 'severity' ], undefined >,
|
severity: Exclude< LogData[ 'severity' ], undefined >,
|
||||||
message: string,
|
message: string,
|
||||||
extraData?: Partial< Exclude< LogData, 'message' | 'severity' > >
|
extraData?: Partial< Exclude< LogData, 'message' | 'severity' > >
|
||||||
): Promise< void > {
|
): Promise< boolean > {
|
||||||
if ( ! canLog() ) {
|
if ( ! canLog( logger ) ) {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await logger?.log( severity, message, extraData );
|
return await logger.log( severity, message, extraData );
|
||||||
} catch ( error ) {
|
} catch ( error ) {
|
||||||
errorLog( 'Failed to send log:', error );
|
errorLog( 'Failed to send log:', error );
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -446,12 +453,12 @@ export async function captureException(
|
||||||
error: Error,
|
error: Error,
|
||||||
extraData?: Partial< LogData >
|
extraData?: Partial< LogData >
|
||||||
) {
|
) {
|
||||||
if ( ! canLog() ) {
|
if ( ! canLog( logger ) ) {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await logger?.error( error, extraData );
|
await logger.error( error, extraData );
|
||||||
} catch ( _error ) {
|
} catch ( _error ) {
|
||||||
errorLog( 'Failed to send log:', _error );
|
errorLog( 'Failed to send log:', _error );
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,8 +3,6 @@
|
||||||
*/
|
*/
|
||||||
import '@wordpress/jest-console';
|
import '@wordpress/jest-console';
|
||||||
import { addFilter, removeFilter } from '@wordpress/hooks';
|
import { addFilter, removeFilter } from '@wordpress/hooks';
|
||||||
import { getSetting } from '@woocommerce/settings';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal dependencies
|
* Internal dependencies
|
||||||
*/
|
*/
|
||||||
|
@ -18,12 +16,6 @@ import {
|
||||||
} from '../remote-logger';
|
} from '../remote-logger';
|
||||||
import { fetchMock } from './__mocks__/fetch';
|
import { fetchMock } from './__mocks__/fetch';
|
||||||
|
|
||||||
jest.mock( '@woocommerce/settings', () => ( {
|
|
||||||
getSetting: jest.fn().mockReturnValue( {
|
|
||||||
isRemoteLoggingEnabled: true,
|
|
||||||
} ),
|
|
||||||
} ) );
|
|
||||||
|
|
||||||
jest.mock( 'tracekit', () => ( {
|
jest.mock( 'tracekit', () => ( {
|
||||||
computeStackTrace: jest.fn().mockReturnValue( {
|
computeStackTrace: jest.fn().mockReturnValue( {
|
||||||
name: 'Error',
|
name: 'Error',
|
||||||
|
@ -118,7 +110,9 @@ describe( 'RemoteLogger', () => {
|
||||||
const payload = JSON.parse( formData.get( 'error' ) );
|
const payload = JSON.parse( formData.get( 'error' ) );
|
||||||
expect( payload[ 'message' ] ).toBe( 'Test error' );
|
expect( payload[ 'message' ] ).toBe( 'Test error' );
|
||||||
expect( payload[ 'severity' ] ).toBe( 'error' );
|
expect( payload[ 'severity' ] ).toBe( 'error' );
|
||||||
expect( payload['trace'] ).toContain( '#1 at testFunction (http://example.com/woocommerce/assets/js/admin/app.min.js:1:1)' );
|
expect( payload[ 'trace' ] ).toContain(
|
||||||
|
'#1 at testFunction (http://example.com/woocommerce/assets/js/admin/app.min.js:1:1)'
|
||||||
|
);
|
||||||
} );
|
} );
|
||||||
|
|
||||||
it( 'should send an error to the API with extra data', async () => {
|
it( 'should send an error to the API with extra data', async () => {
|
||||||
|
@ -141,8 +135,14 @@ describe( 'RemoteLogger', () => {
|
||||||
const payload = JSON.parse( formData.get( 'error' ) );
|
const payload = JSON.parse( formData.get( 'error' ) );
|
||||||
expect( payload[ 'message' ] ).toBe( 'Test error' );
|
expect( payload[ 'message' ] ).toBe( 'Test error' );
|
||||||
expect( payload[ 'severity' ] ).toBe( 'warning' );
|
expect( payload[ 'severity' ] ).toBe( 'warning' );
|
||||||
expect( payload['tags'] ).toEqual( ["woocommerce", "js", "custom-tag"]);
|
expect( payload[ 'tags' ] ).toEqual( [
|
||||||
expect( payload['trace'] ).toContain( '#1 at testFunction (http://example.com/woocommerce/assets/js/admin/app.min.js:1:1)' );
|
'woocommerce',
|
||||||
|
'js',
|
||||||
|
'custom-tag',
|
||||||
|
] );
|
||||||
|
expect( payload[ 'trace' ] ).toContain(
|
||||||
|
'#1 at testFunction (http://example.com/woocommerce/assets/js/admin/app.min.js:1:1)'
|
||||||
|
);
|
||||||
} );
|
} );
|
||||||
} );
|
} );
|
||||||
|
|
||||||
|
@ -305,31 +305,23 @@ describe( 'RemoteLogger', () => {
|
||||||
} );
|
} );
|
||||||
} );
|
} );
|
||||||
|
|
||||||
|
global.window.wcSettings = {
|
||||||
|
isRemoteLoggingEnabled: true,
|
||||||
|
};
|
||||||
|
|
||||||
describe( 'init', () => {
|
describe( 'init', () => {
|
||||||
beforeEach( () => {
|
beforeEach( () => {
|
||||||
jest.clearAllMocks();
|
jest.clearAllMocks();
|
||||||
|
|
||||||
( getSetting as jest.Mock ).mockImplementation(
|
global.window.wcSettings = {
|
||||||
( key, defaultValue ) => {
|
isRemoteLoggingEnabled: true,
|
||||||
if ( key === 'isRemoteLoggingEnabled' ) {
|
};
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return defaultValue;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
} );
|
} );
|
||||||
|
|
||||||
it( 'should not initialize or log when remote logging is disabled', () => {
|
it( 'should not initialize or log when remote logging is disabled', () => {
|
||||||
// Mock the getSetting function to return false for isRemoteLoggingEnabled
|
global.window.wcSettings = {
|
||||||
( getSetting as jest.Mock ).mockImplementation(
|
isRemoteLoggingEnabled: false,
|
||||||
( key, defaultValue ) => {
|
};
|
||||||
if ( key === 'isRemoteLoggingEnabled' ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return defaultValue;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
init( { errorRateLimitMs: 1000 } );
|
init( { errorRateLimitMs: 1000 } );
|
||||||
log( 'info', 'Test message' );
|
log( 'info', 'Test message' );
|
||||||
expect( fetchMock ).not.toHaveBeenCalled();
|
expect( fetchMock ).not.toHaveBeenCalled();
|
||||||
|
@ -353,15 +345,9 @@ describe( 'init', () => {
|
||||||
|
|
||||||
describe( 'log', () => {
|
describe( 'log', () => {
|
||||||
it( 'should not log if remote logging is disabled', () => {
|
it( 'should not log if remote logging is disabled', () => {
|
||||||
( getSetting as jest.Mock ).mockImplementation(
|
global.window.wcSettings = {
|
||||||
( key, defaultValue ) => {
|
isRemoteLoggingEnabled: false,
|
||||||
if ( key === 'isRemoteLoggingEnabled' ) {
|
};
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return defaultValue;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
log( 'info', 'Test message' );
|
log( 'info', 'Test message' );
|
||||||
expect( fetchMock ).not.toHaveBeenCalled();
|
expect( fetchMock ).not.toHaveBeenCalled();
|
||||||
} );
|
} );
|
||||||
|
@ -369,15 +355,9 @@ describe( 'log', () => {
|
||||||
|
|
||||||
describe( 'captureException', () => {
|
describe( 'captureException', () => {
|
||||||
it( 'should not log error if remote logging is disabled', () => {
|
it( 'should not log error if remote logging is disabled', () => {
|
||||||
( getSetting as jest.Mock ).mockImplementation(
|
global.window.wcSettings = {
|
||||||
( key, defaultValue ) => {
|
isRemoteLoggingEnabled: false,
|
||||||
if ( key === 'isRemoteLoggingEnabled' ) {
|
};
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return defaultValue;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
captureException( new Error( 'Test error' ) );
|
captureException( new Error( 'Test error' ) );
|
||||||
expect( fetchMock ).not.toHaveBeenCalled();
|
expect( fetchMock ).not.toHaveBeenCalled();
|
||||||
} );
|
} );
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
declare global {
|
declare global {
|
||||||
interface Window {
|
interface Window {
|
||||||
wcTracks: {
|
wcSettings?: {
|
||||||
isEnabled: boolean;
|
isRemoteLoggingEnabled: boolean;
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -63,3 +63,4 @@ require 'live-branches/manifest.php';
|
||||||
require 'live-branches/install.php';
|
require 'live-branches/install.php';
|
||||||
require 'remote-spec-validator/class-wca-test-helper-remote-spec-validator.php';
|
require 'remote-spec-validator/class-wca-test-helper-remote-spec-validator.php';
|
||||||
require 'remote-inbox-notifications/class-wca-test-helper-remote-inbox-notifications.php';
|
require 'remote-inbox-notifications/class-wca-test-helper-remote-inbox-notifications.php';
|
||||||
|
require 'remote-logging/remote-logging.php';
|
||||||
|
|
|
@ -0,0 +1,126 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
defined( 'ABSPATH' ) || exit;
|
||||||
|
|
||||||
|
use Automattic\WooCommerce\Internal\Logging\RemoteLogger;
|
||||||
|
|
||||||
|
register_woocommerce_admin_test_helper_rest_route(
|
||||||
|
'/remote-logging/status',
|
||||||
|
'get_remote_logging_status',
|
||||||
|
array(
|
||||||
|
'methods' => 'GET',
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
register_woocommerce_admin_test_helper_rest_route(
|
||||||
|
'/remote-logging/toggle',
|
||||||
|
'toggle_remote_logging',
|
||||||
|
array(
|
||||||
|
'methods' => 'POST',
|
||||||
|
'args' => array(
|
||||||
|
'enable' => array(
|
||||||
|
'required' => true,
|
||||||
|
'type' => 'boolean',
|
||||||
|
'sanitize_callback' => 'rest_sanitize_boolean',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
register_woocommerce_admin_test_helper_rest_route(
|
||||||
|
'/remote-logging/log-event',
|
||||||
|
'log_remote_event',
|
||||||
|
array(
|
||||||
|
'methods' => 'POST',
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
register_woocommerce_admin_test_helper_rest_route(
|
||||||
|
'/remote-logging/reset-rate-limit',
|
||||||
|
'reset_php_rate_limit',
|
||||||
|
array(
|
||||||
|
'methods' => 'POST',
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the remote logging status.
|
||||||
|
*
|
||||||
|
* @return WP_REST_Response The response object.
|
||||||
|
*/
|
||||||
|
function get_remote_logging_status() {
|
||||||
|
$remote_logger = wc_get_container()->get( RemoteLogger::class );
|
||||||
|
|
||||||
|
return new WP_REST_Response(
|
||||||
|
array(
|
||||||
|
'isEnabled' => $remote_logger->is_remote_logging_allowed(),
|
||||||
|
'wpEnvironment' => wp_get_environment_type(),
|
||||||
|
),
|
||||||
|
200
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Toggle remote logging on or off.
|
||||||
|
*
|
||||||
|
* @param WP_REST_Request $request The request object.
|
||||||
|
* @return WP_REST_Response The response object.
|
||||||
|
*/
|
||||||
|
function toggle_remote_logging( $request ) {
|
||||||
|
$enable = $request->get_param( 'enable' );
|
||||||
|
|
||||||
|
if ( $enable ) {
|
||||||
|
update_option( 'woocommerce_feature_remote_logging_enabled', 'yes' );
|
||||||
|
update_option( 'woocommerce_allow_tracking', 'yes' );
|
||||||
|
update_option( 'woocommerce_remote_variant_assignment', 1 );
|
||||||
|
} else {
|
||||||
|
update_option( 'woocommerce_feature_remote_logging_enabled', 'no' );
|
||||||
|
}
|
||||||
|
|
||||||
|
$remote_logger = wc_get_container()->get( RemoteLogger::class );
|
||||||
|
return new WP_REST_Response(
|
||||||
|
array(
|
||||||
|
'isEnabled' => $remote_logger->is_remote_logging_allowed(),
|
||||||
|
),
|
||||||
|
200
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log a remote event for testing purposes.
|
||||||
|
*
|
||||||
|
* @return WP_REST_Response The response object.
|
||||||
|
*/
|
||||||
|
function log_remote_event() {
|
||||||
|
$remote_logger = wc_get_container()->get( RemoteLogger::class );
|
||||||
|
$result = $remote_logger->handle(
|
||||||
|
time(),
|
||||||
|
'critical',
|
||||||
|
'Test PHP event from WC Beta Tester',
|
||||||
|
array( 'source' => 'wc-beta-tester' )
|
||||||
|
);
|
||||||
|
|
||||||
|
if ( $result ) {
|
||||||
|
return new WP_REST_Response( array( 'message' => 'Remote event logged successfully.' ), 200 );
|
||||||
|
} else {
|
||||||
|
return new WP_REST_Response( array( 'message' => 'Failed to log remote event.' ), 500 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reset the PHP rate limit.
|
||||||
|
*
|
||||||
|
* @return WP_REST_Response The response object.
|
||||||
|
*/
|
||||||
|
function reset_php_rate_limit() {
|
||||||
|
global $wpdb;
|
||||||
|
$wpdb->query(
|
||||||
|
"DELETE FROM {$wpdb->prefix}wc_rate_limits"
|
||||||
|
);
|
||||||
|
|
||||||
|
WC_Cache_Helper::invalidate_cache_group( WC_Rate_Limiter::CACHE_GROUP );
|
||||||
|
|
||||||
|
return new WP_REST_Response( array( 'success' => true ), 200 );
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
Significance: minor
|
||||||
|
Type: add
|
||||||
|
|
||||||
|
Add remote logging tool
|
|
@ -17,6 +17,7 @@
|
||||||
"@types/wordpress__plugins": "3.0.0",
|
"@types/wordpress__plugins": "3.0.0",
|
||||||
"@woocommerce/dependency-extraction-webpack-plugin": "workspace:*",
|
"@woocommerce/dependency-extraction-webpack-plugin": "workspace:*",
|
||||||
"@woocommerce/eslint-plugin": "workspace:*",
|
"@woocommerce/eslint-plugin": "workspace:*",
|
||||||
|
"@woocommerce/remote-logging": "workspace:*",
|
||||||
"@wordpress/env": "^9.7.0",
|
"@wordpress/env": "^9.7.0",
|
||||||
"@wordpress/prettier-config": "2.17.0",
|
"@wordpress/prettier-config": "2.17.0",
|
||||||
"@wordpress/scripts": "^19.2.4",
|
"@wordpress/scripts": "^19.2.4",
|
||||||
|
|
|
@ -7,14 +7,13 @@ import { applyFilters } from '@wordpress/hooks';
|
||||||
/**
|
/**
|
||||||
* Internal dependencies
|
* Internal dependencies
|
||||||
*/
|
*/
|
||||||
import { AdminNotes } from '../admin-notes';
|
|
||||||
import { default as Tools } from '../tools';
|
import { default as Tools } from '../tools';
|
||||||
import { default as Options } from '../options';
|
import { default as Options } from '../options';
|
||||||
import { default as Experiments } from '../experiments';
|
import { default as Experiments } from '../experiments';
|
||||||
import { default as Features } from '../features';
|
import { default as Features } from '../features';
|
||||||
import { default as RestAPIFilters } from '../rest-api-filters';
|
import { default as RestAPIFilters } from '../rest-api-filters';
|
||||||
import RemoteSpecValidator from '../remote-spec-validator';
|
|
||||||
import RemoteInboxNotifications from '../remote-inbox-notifications';
|
import RemoteInboxNotifications from '../remote-inbox-notifications';
|
||||||
|
import RemoteLogging from '../remote-logging';
|
||||||
|
|
||||||
const tabs = applyFilters( 'woocommerce_admin_test_helper_tabs', [
|
const tabs = applyFilters( 'woocommerce_admin_test_helper_tabs', [
|
||||||
{
|
{
|
||||||
|
@ -47,6 +46,11 @@ const tabs = applyFilters( 'woocommerce_admin_test_helper_tabs', [
|
||||||
title: 'Remote Inbox Notifications',
|
title: 'Remote Inbox Notifications',
|
||||||
content: <RemoteInboxNotifications />,
|
content: <RemoteInboxNotifications />,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'remote-logging',
|
||||||
|
title: 'Remote Logging',
|
||||||
|
content: <RemoteLogging />,
|
||||||
|
},
|
||||||
] );
|
] );
|
||||||
|
|
||||||
export function App() {
|
export function App() {
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
* External dependencies
|
* External dependencies
|
||||||
*/
|
*/
|
||||||
import { createRoot } from '@wordpress/element';
|
import { createRoot } from '@wordpress/element';
|
||||||
|
import { addFilter } from '@wordpress/hooks';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal dependencies
|
* Internal dependencies
|
||||||
|
@ -10,6 +11,7 @@ import { App } from './app';
|
||||||
import './index.scss';
|
import './index.scss';
|
||||||
import './example-fills/experimental-woocommerce-wcpay-feature';
|
import './example-fills/experimental-woocommerce-wcpay-feature';
|
||||||
import { registerProductEditorDevTools } from './product-editor-dev-tools';
|
import { registerProductEditorDevTools } from './product-editor-dev-tools';
|
||||||
|
import { registerExceptionFilter } from './remote-logging/register-exception-filter';
|
||||||
|
|
||||||
const appRoot = document.getElementById(
|
const appRoot = document.getElementById(
|
||||||
'woocommerce-admin-test-helper-app-root'
|
'woocommerce-admin-test-helper-app-root'
|
||||||
|
@ -20,3 +22,4 @@ if ( appRoot ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
registerProductEditorDevTools();
|
registerProductEditorDevTools();
|
||||||
|
registerExceptionFilter();
|
||||||
|
|
|
@ -43,7 +43,6 @@ export function setNotice( notice ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function* deleteOption( optionName ) {
|
export function* deleteOption( optionName ) {
|
||||||
try {
|
|
||||||
yield apiFetch( {
|
yield apiFetch( {
|
||||||
method: 'DELETE',
|
method: 'DELETE',
|
||||||
path: `${ API_NAMESPACE }/options/${ optionName }`,
|
path: `${ API_NAMESPACE }/options/${ optionName }`,
|
||||||
|
@ -52,15 +51,18 @@ export function* deleteOption( optionName ) {
|
||||||
type: TYPES.DELETE_OPTION,
|
type: TYPES.DELETE_OPTION,
|
||||||
optionName,
|
optionName,
|
||||||
};
|
};
|
||||||
} catch {
|
|
||||||
throw new Error();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function* saveOption( optionName, newOptionValue ) {
|
export function* saveOption( optionName, newOptionValue ) {
|
||||||
try {
|
try {
|
||||||
const payload = {};
|
const payload = {};
|
||||||
|
try {
|
||||||
|
// If the option value is a JSON string, parse it.
|
||||||
payload[ optionName ] = JSON.parse( newOptionValue );
|
payload[ optionName ] = JSON.parse( newOptionValue );
|
||||||
|
} catch ( error ) {
|
||||||
|
// If it's not a JSON string, just use the value as is.
|
||||||
|
payload[ optionName ] = newOptionValue;
|
||||||
|
}
|
||||||
yield apiFetch( {
|
yield apiFetch( {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
path: '/wc-admin/options',
|
path: '/wc-admin/options',
|
||||||
|
@ -71,11 +73,11 @@ export function* saveOption( optionName, newOptionValue ) {
|
||||||
status: 'success',
|
status: 'success',
|
||||||
message: optionName + ' has been saved.',
|
message: optionName + ' has been saved.',
|
||||||
} );
|
} );
|
||||||
} catch {
|
} catch ( error ) {
|
||||||
yield setNotice( {
|
yield setNotice( {
|
||||||
status: 'error',
|
status: 'error',
|
||||||
message: 'Unable to save ' + optionName,
|
message: 'Unable to save ' + optionName,
|
||||||
} );
|
} );
|
||||||
throw new Error();
|
throw error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,14 +17,10 @@ export function* getOptions( search ) {
|
||||||
|
|
||||||
yield setLoadingState( true );
|
yield setLoadingState( true );
|
||||||
|
|
||||||
try {
|
|
||||||
const response = yield apiFetch( {
|
const response = yield apiFetch( {
|
||||||
path,
|
path,
|
||||||
} );
|
} );
|
||||||
yield setOptions( response );
|
yield setOptions( response );
|
||||||
} catch ( error ) {
|
|
||||||
throw new Error();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function* getOptionForEditing( optionName ) {
|
export function* getOptionForEditing( optionName ) {
|
||||||
|
@ -41,7 +37,6 @@ export function* getOptionForEditing( optionName ) {
|
||||||
|
|
||||||
const path = '/wc-admin/options?options=' + optionName;
|
const path = '/wc-admin/options?options=' + optionName;
|
||||||
|
|
||||||
try {
|
|
||||||
const response = yield apiFetch( {
|
const response = yield apiFetch( {
|
||||||
path,
|
path,
|
||||||
} );
|
} );
|
||||||
|
@ -55,7 +50,4 @@ export function* getOptionForEditing( optionName ) {
|
||||||
name: optionName,
|
name: optionName,
|
||||||
content,
|
content,
|
||||||
} );
|
} );
|
||||||
} catch ( error ) {
|
|
||||||
throw new Error( error );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,323 @@
|
||||||
|
/**
|
||||||
|
* External dependencies
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { useState, useEffect } from '@wordpress/element';
|
||||||
|
import { Button, ToggleControl, Notice, Spinner } from '@wordpress/components';
|
||||||
|
import apiFetch from '@wordpress/api-fetch';
|
||||||
|
import { log, init as initRemoteLogging } from '@woocommerce/remote-logging';
|
||||||
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
|
// @ts-ignore no types
|
||||||
|
// eslint-disable-next-line @woocommerce/dependency-group
|
||||||
|
import { dispatch } from '@wordpress/data';
|
||||||
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
|
// @ts-ignore no types
|
||||||
|
// eslint-disable-next-line @woocommerce/dependency-group
|
||||||
|
import { STORE_KEY as OPTIONS_STORE_NAME } from '../options/data/constants';
|
||||||
|
|
||||||
|
export const API_NAMESPACE = '/wc-admin-test-helper';
|
||||||
|
|
||||||
|
interface RemoteLoggingStatus {
|
||||||
|
isEnabled: boolean;
|
||||||
|
wpEnvironment: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface NoticeState {
|
||||||
|
status: 'success' | 'error' | 'warning' | 'info';
|
||||||
|
message: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
function RemoteLogging() {
|
||||||
|
const [ isRemoteLoggingEnabled, setIsRemoteLoggingEnabled ] = useState<
|
||||||
|
boolean | null
|
||||||
|
>( null );
|
||||||
|
const [ wpEnvironment, setWpEnvironment ] = useState< string >( '' );
|
||||||
|
const [ notice, setNotice ] = useState< NoticeState | null >( null );
|
||||||
|
|
||||||
|
useEffect( () => {
|
||||||
|
const fetchRemoteLoggingStatus = async () => {
|
||||||
|
try {
|
||||||
|
const response: RemoteLoggingStatus = await apiFetch( {
|
||||||
|
path: `${ API_NAMESPACE }/remote-logging/status`,
|
||||||
|
} );
|
||||||
|
setIsRemoteLoggingEnabled( response.isEnabled );
|
||||||
|
setWpEnvironment( response.wpEnvironment );
|
||||||
|
} catch ( error ) {
|
||||||
|
setNotice( {
|
||||||
|
status: 'error',
|
||||||
|
message: 'Failed to fetch remote logging status.',
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
fetchRemoteLoggingStatus();
|
||||||
|
}, [] );
|
||||||
|
|
||||||
|
const toggleRemoteLogging = async () => {
|
||||||
|
try {
|
||||||
|
const response: RemoteLoggingStatus = await apiFetch( {
|
||||||
|
path: `${ API_NAMESPACE }/remote-logging/toggle`,
|
||||||
|
method: 'POST',
|
||||||
|
data: { enable: ! isRemoteLoggingEnabled },
|
||||||
|
} );
|
||||||
|
setIsRemoteLoggingEnabled( response.isEnabled );
|
||||||
|
|
||||||
|
window.wcSettings.isRemoteLoggingEnabled = response.isEnabled;
|
||||||
|
} catch ( error ) {
|
||||||
|
setNotice( {
|
||||||
|
status: 'error',
|
||||||
|
message: `Failed to update remote logging status. ${ JSON.stringify(
|
||||||
|
error
|
||||||
|
) }`,
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( window.wcSettings.isRemoteLoggingEnabled ) {
|
||||||
|
initRemoteLogging( {
|
||||||
|
errorRateLimitMs: 60000, // 1 minute
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const simulatePhpException = async ( context: 'core' | 'beta-tester' ) => {
|
||||||
|
try {
|
||||||
|
await dispatch( OPTIONS_STORE_NAME ).saveOption(
|
||||||
|
'wc_beta_tester_simulate_woocommerce_php_error',
|
||||||
|
context
|
||||||
|
);
|
||||||
|
setNotice( {
|
||||||
|
status: 'success',
|
||||||
|
message: `Please refresh your browser to trigger the PHP exception in ${ context } context.`,
|
||||||
|
} );
|
||||||
|
} catch ( error ) {
|
||||||
|
setNotice( {
|
||||||
|
status: 'error',
|
||||||
|
message: `Failed to trigger PHP exception test in ${ context } context. ${ JSON.stringify(
|
||||||
|
error
|
||||||
|
) }`,
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const logPhpEvent = async () => {
|
||||||
|
try {
|
||||||
|
await apiFetch( {
|
||||||
|
path: `${ API_NAMESPACE }/remote-logging/log-event`,
|
||||||
|
method: 'POST',
|
||||||
|
} );
|
||||||
|
setNotice( {
|
||||||
|
status: 'success',
|
||||||
|
message: 'Remote event logged successfully.',
|
||||||
|
} );
|
||||||
|
} catch ( error ) {
|
||||||
|
setNotice( {
|
||||||
|
status: 'error',
|
||||||
|
message: `Failed to log remote event.`,
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const resetPhpRateLimit = async () => {
|
||||||
|
try {
|
||||||
|
await apiFetch( {
|
||||||
|
path: `${ API_NAMESPACE }/remote-logging/reset-rate-limit`,
|
||||||
|
method: 'POST',
|
||||||
|
} );
|
||||||
|
setNotice( {
|
||||||
|
status: 'success',
|
||||||
|
message: 'PHP rate limit reset successfully.',
|
||||||
|
} );
|
||||||
|
} catch ( error ) {
|
||||||
|
setNotice( {
|
||||||
|
status: 'error',
|
||||||
|
message: `Failed to reset PHP rate limit. ${ JSON.stringify(
|
||||||
|
error
|
||||||
|
) }`,
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const simulateException = async ( context: 'core' | 'beta-tester' ) => {
|
||||||
|
try {
|
||||||
|
await dispatch( OPTIONS_STORE_NAME ).saveOption(
|
||||||
|
'wc_beta_tester_simulate_woocommerce_js_error',
|
||||||
|
context
|
||||||
|
);
|
||||||
|
|
||||||
|
if ( context === 'core' ) {
|
||||||
|
setNotice( {
|
||||||
|
status: 'success',
|
||||||
|
message: `Please go to WooCommerce pages to trigger the JS exception in woocommerce context.`,
|
||||||
|
} );
|
||||||
|
} else {
|
||||||
|
setNotice( {
|
||||||
|
status: 'success',
|
||||||
|
message:
|
||||||
|
'Please refresh your browser to trigger the JS exception in woocommerce beta tester context.',
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
} catch ( error ) {
|
||||||
|
setNotice( {
|
||||||
|
status: 'error',
|
||||||
|
message: `Failed to set up JS exception test`,
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const logJsEvent = async () => {
|
||||||
|
try {
|
||||||
|
const result = await log(
|
||||||
|
'info',
|
||||||
|
'Test JS event from WooCommerce Beta Tester',
|
||||||
|
{
|
||||||
|
extra: {
|
||||||
|
source: 'wc-beta-tester',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
if ( ! result ) {
|
||||||
|
throw new Error();
|
||||||
|
}
|
||||||
|
|
||||||
|
setNotice( {
|
||||||
|
status: 'success',
|
||||||
|
message: 'JS event logged successfully.',
|
||||||
|
} );
|
||||||
|
} catch ( error ) {
|
||||||
|
setNotice( {
|
||||||
|
status: 'error',
|
||||||
|
message:
|
||||||
|
'Failed to log JS event. Try enabling debug mode `window.localStorage.setItem( "debug", "wc:remote-logging" )` to see the details.',
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const resetJsRateLimit = () => {
|
||||||
|
window.localStorage.removeItem(
|
||||||
|
'wc_remote_logging_last_error_sent_time'
|
||||||
|
);
|
||||||
|
setNotice( {
|
||||||
|
status: 'success',
|
||||||
|
message: 'JS rate limit reset successfully.',
|
||||||
|
} );
|
||||||
|
};
|
||||||
|
|
||||||
|
if ( isRemoteLoggingEnabled === null ) {
|
||||||
|
return <Spinner />;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div id="wc-admin-test-helper-remote-logging">
|
||||||
|
<h2>Remote Logging</h2>
|
||||||
|
{ notice && (
|
||||||
|
<div style={ { marginBottom: '12px' } }>
|
||||||
|
<Notice
|
||||||
|
status={ notice.status }
|
||||||
|
onRemove={ () => setNotice( null ) }
|
||||||
|
>
|
||||||
|
{ notice.message }
|
||||||
|
</Notice>
|
||||||
|
</div>
|
||||||
|
) }
|
||||||
|
|
||||||
|
{ ! isRemoteLoggingEnabled && (
|
||||||
|
<p className="helper-text" style={ { marginBottom: '12px' } }>
|
||||||
|
Enable remote logging to test log event functionality.
|
||||||
|
</p>
|
||||||
|
) }
|
||||||
|
|
||||||
|
{ ( wpEnvironment === 'local' ||
|
||||||
|
wpEnvironment === 'development' ) && (
|
||||||
|
<div style={ { marginBottom: '12px' } }>
|
||||||
|
<Notice status="warning" isDismissible={ false }>
|
||||||
|
Warning: You are in a { wpEnvironment } environment.
|
||||||
|
Remote logging may not work as expected. Please set
|
||||||
|
<code>WP_ENVIRONMENT_TYPE</code> to{ ' ' }
|
||||||
|
<code>production</code>
|
||||||
|
in your wp-config.php file to test remote logging.
|
||||||
|
</Notice>
|
||||||
|
</div>
|
||||||
|
) }
|
||||||
|
|
||||||
|
<ToggleControl
|
||||||
|
label="Enable Remote Logging"
|
||||||
|
checked={ isRemoteLoggingEnabled }
|
||||||
|
onChange={ toggleRemoteLogging }
|
||||||
|
/>
|
||||||
|
|
||||||
|
<hr />
|
||||||
|
<h3>PHP Integration</h3>
|
||||||
|
<p>Test PHP remote logging functionality:</p>
|
||||||
|
<div className="button-group" style={ { marginBottom: '20px' } }>
|
||||||
|
<Button
|
||||||
|
variant="secondary"
|
||||||
|
onClick={ () => simulatePhpException( 'core' ) }
|
||||||
|
style={ { marginRight: '10px' } }
|
||||||
|
>
|
||||||
|
Simulate Core Exception
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
variant="secondary"
|
||||||
|
onClick={ () => simulatePhpException( 'beta-tester' ) }
|
||||||
|
style={ { marginRight: '10px' } }
|
||||||
|
>
|
||||||
|
Simulate Beta Tester Exception
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
variant="secondary"
|
||||||
|
onClick={ logPhpEvent }
|
||||||
|
disabled={ ! isRemoteLoggingEnabled }
|
||||||
|
style={ { marginRight: '10px' } }
|
||||||
|
>
|
||||||
|
Log PHP Event
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
variant="secondary"
|
||||||
|
onClick={ resetPhpRateLimit }
|
||||||
|
disabled={ ! isRemoteLoggingEnabled }
|
||||||
|
>
|
||||||
|
Reset Rate Limit
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr className="section-divider" style={ { margin: '20px 0' } } />
|
||||||
|
|
||||||
|
<h3>JavaScript Integration</h3>
|
||||||
|
<p>Test JavaScript remote logging functionality:</p>
|
||||||
|
<div className="button-group" style={ { marginBottom: '20px' } }>
|
||||||
|
<Button
|
||||||
|
variant="secondary"
|
||||||
|
onClick={ () => simulateException( 'core' ) }
|
||||||
|
style={ { marginRight: '10px' } }
|
||||||
|
>
|
||||||
|
Simulate Core Exception
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
variant="secondary"
|
||||||
|
onClick={ () => simulateException( 'beta-tester' ) }
|
||||||
|
style={ { marginRight: '10px' } }
|
||||||
|
>
|
||||||
|
Simulate Beta Tester Exception
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
variant="secondary"
|
||||||
|
onClick={ logJsEvent }
|
||||||
|
disabled={ ! isRemoteLoggingEnabled }
|
||||||
|
style={ { marginRight: '10px' } }
|
||||||
|
>
|
||||||
|
Log Event
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
variant="secondary"
|
||||||
|
onClick={ resetJsRateLimit }
|
||||||
|
disabled={ ! isRemoteLoggingEnabled }
|
||||||
|
>
|
||||||
|
Reset Rate Limit
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default RemoteLogging;
|
|
@ -0,0 +1,93 @@
|
||||||
|
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
||||||
|
/* eslint-disable @woocommerce/dependency-group */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* External dependencies
|
||||||
|
*/
|
||||||
|
import { addFilter } from '@wordpress/hooks';
|
||||||
|
|
||||||
|
import apiFetch from '@wordpress/api-fetch';
|
||||||
|
// @ts-ignore no types
|
||||||
|
import { dispatch } from '@wordpress/data';
|
||||||
|
/**
|
||||||
|
* Internal dependencies
|
||||||
|
*/
|
||||||
|
import { API_NAMESPACE } from './';
|
||||||
|
// @ts-ignore no types
|
||||||
|
import { STORE_KEY as OPTIONS_STORE_NAME } from '../options/data/constants';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the options for simulating a WooCommerce JavaScript error.
|
||||||
|
*
|
||||||
|
* @return {Promise<Array|null>} The options if available, null otherwise.
|
||||||
|
*/
|
||||||
|
const getSimulateErrorOptions = async () => {
|
||||||
|
try {
|
||||||
|
const path = `${ API_NAMESPACE }/options?search=wc_beta_tester_simulate_woocommerce_js_error`;
|
||||||
|
|
||||||
|
const options = await apiFetch<
|
||||||
|
[
|
||||||
|
{
|
||||||
|
option_value: string;
|
||||||
|
option_name: string;
|
||||||
|
option_id: number;
|
||||||
|
}
|
||||||
|
]
|
||||||
|
>( {
|
||||||
|
path,
|
||||||
|
} );
|
||||||
|
return options && options.length > 0 ? options : null;
|
||||||
|
} catch ( error ) {
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.error( 'Error retrieving simulate error options:', error );
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes the option used for simulating WooCommerce JavaScript errors.
|
||||||
|
*/
|
||||||
|
const deleteSimulateErrorOption = async () => {
|
||||||
|
await dispatch( OPTIONS_STORE_NAME ).deleteOption(
|
||||||
|
'wc_beta_tester_simulate_woocommerce_js_error'
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a filter to throw an exception in the WooCommerce core context.
|
||||||
|
*/
|
||||||
|
const addCoreExceptionFilter = () => {
|
||||||
|
addFilter( 'woocommerce_admin_pages_list', 'wc-beta-tester', () => {
|
||||||
|
deleteSimulateErrorOption();
|
||||||
|
|
||||||
|
throw new Error(
|
||||||
|
'Test JS exception in WC Core context via WC Beta Tester'
|
||||||
|
);
|
||||||
|
} );
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Throws an exception specific to the WooCommerce Beta Tester context.
|
||||||
|
*/
|
||||||
|
const throwBetaTesterException = () => {
|
||||||
|
throw new Error( 'Test JS exception from WooCommerce Beta Tester' );
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers an exception filter for simulating JavaScript errors in WooCommerce.
|
||||||
|
* This function is used for testing purposes in the WooCommerce Beta Tester plugin.
|
||||||
|
*/
|
||||||
|
export const registerExceptionFilter = async () => {
|
||||||
|
const options = await getSimulateErrorOptions();
|
||||||
|
if ( ! options ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const context = options[ 0 ].option_value;
|
||||||
|
if ( context === 'core' ) {
|
||||||
|
addCoreExceptionFilter();
|
||||||
|
} else {
|
||||||
|
deleteSimulateErrorOption();
|
||||||
|
throwBetaTesterException();
|
||||||
|
}
|
||||||
|
};
|
|
@ -0,0 +1,9 @@
|
||||||
|
declare global {
|
||||||
|
interface Window {
|
||||||
|
wcSettings: {
|
||||||
|
isRemoteLoggingEnabled: boolean;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export {};
|
|
@ -138,5 +138,28 @@ add_action(
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simulate a WooCommerce error for remote logging testing.
|
||||||
|
*
|
||||||
|
* @throws Exception A simulated WooCommerce error if the option is set.
|
||||||
|
*/
|
||||||
|
function simulate_woocommerce_error() {
|
||||||
|
throw new Exception( 'Simulated WooCommerce error for remote logging test' );
|
||||||
|
}
|
||||||
|
|
||||||
|
$simulate_error = get_option( 'wc_beta_tester_simulate_woocommerce_php_error', false );
|
||||||
|
|
||||||
|
if ( $simulate_error ) {
|
||||||
|
delete_option( 'wc_beta_tester_simulate_woocommerce_php_error' );
|
||||||
|
|
||||||
|
if ( 'core' === $simulate_error ) {
|
||||||
|
add_action( 'woocommerce_loaded', 'simulate_woocommerce_error' );
|
||||||
|
} elseif ( 'beta-tester' === $simulate_error ) {
|
||||||
|
throw new Exception( 'Test PHP exception from WooCommerce Beta Tester' );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Initialize the live branches feature.
|
// Initialize the live branches feature.
|
||||||
require_once dirname( __FILE__ ) . '/includes/class-wc-beta-tester-live-branches.php';
|
require_once dirname( __FILE__ ) . '/includes/class-wc-beta-tester-live-branches.php';
|
||||||
|
|
|
@ -3916,6 +3916,9 @@ importers:
|
||||||
'@woocommerce/eslint-plugin':
|
'@woocommerce/eslint-plugin':
|
||||||
specifier: workspace:*
|
specifier: workspace:*
|
||||||
version: link:../../packages/js/eslint-plugin
|
version: link:../../packages/js/eslint-plugin
|
||||||
|
'@woocommerce/remote-logging':
|
||||||
|
specifier: workspace:*
|
||||||
|
version: link:../../packages/js/remote-logging
|
||||||
'@wordpress/env':
|
'@wordpress/env':
|
||||||
specifier: ^9.7.0
|
specifier: ^9.7.0
|
||||||
version: 9.7.0
|
version: 9.7.0
|
||||||
|
@ -21800,7 +21803,7 @@ packages:
|
||||||
react-with-direction@1.4.0:
|
react-with-direction@1.4.0:
|
||||||
resolution: {integrity: sha512-ybHNPiAmaJpoWwugwqry9Hd1Irl2hnNXlo/2SXQBwbLn/jGMauMS2y9jw+ydyX5V9ICryCqObNSthNt5R94xpg==}
|
resolution: {integrity: sha512-ybHNPiAmaJpoWwugwqry9Hd1Irl2hnNXlo/2SXQBwbLn/jGMauMS2y9jw+ydyX5V9ICryCqObNSthNt5R94xpg==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
react: ^0.14 || ^15 || ^16
|
react: ^17.0.2
|
||||||
react-dom: ^0.14 || ^15 || ^16
|
react-dom: ^0.14 || ^15 || ^16
|
||||||
|
|
||||||
react-with-styles-interface-css@4.0.3:
|
react-with-styles-interface-css@4.0.3:
|
||||||
|
|
Loading…
Reference in New Issue