Fix bin/publish: use correct .env path for rspade_system Fix bin/publish script: prevent grep exit code 1 from terminating script 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
566 lines
24 KiB
PHP
Executable File
566 lines
24 KiB
PHP
Executable File
<?php
|
|
/**
|
|
* CODING CONVENTION:
|
|
* This file follows the coding convention where variable_names and function_names
|
|
* use snake_case (underscore_wherever_possible).
|
|
*/
|
|
|
|
namespace App\RSpade\Commands\Rsx;
|
|
|
|
use Illuminate\Console\Command;
|
|
use Symfony\Component\Process\Process;
|
|
use App\RSpade\Core\Debug\Debugger;
|
|
|
|
/**
|
|
* RSX Route Debug Command
|
|
* ========================
|
|
*
|
|
* PURPOSE:
|
|
* This is a comprehensive route debugging tool designed for the RSpade project.
|
|
* It uses Playwright to launch a real browser and fetch a route, capturing extensive
|
|
* diagnostic information about the request, response, JavaScript execution, and logs.
|
|
*
|
|
* HOW IT WORKS:
|
|
* 1. Rotates all development logs for clean slate debugging
|
|
* 2. Launches a headless Chromium browser via Playwright
|
|
* 3. Navigates to the specified route on localhost
|
|
* 4. Captures response, console output, XHR requests, DOM state, and more
|
|
* 5. Outputs results in a terse, log-like format for easy debugging
|
|
* 6. Rotates logs again after test for clean slate on next run
|
|
*
|
|
* KEY FEATURES:
|
|
* - Backdoor authentication: Use --user-id to bypass login and test as any user
|
|
* - Plain text error output: Errors returned as plain text with stack traces
|
|
* - Console capture: JavaScript errors and logs captured (--console-log for all)
|
|
* - XHR/fetch tracking: Monitor API calls with --xhr-dump or --xhr-list
|
|
* - Element verification: Check DOM elements with --expect-element
|
|
* - HTML extraction: Get element HTML with --dump-element
|
|
* - Storage inspection: View localStorage/sessionStorage with --storage
|
|
* - Form inspection: List all input elements with --input-elements
|
|
* - Cookie display: Show all cookies with --cookies
|
|
* - Redirect following: Track redirect chains with --follow-redirects
|
|
* - POST requests: Send JSON data with --post
|
|
* - Headers inspection: Display all headers with --headers
|
|
* - Log integration: Show Laravel/nginx logs with --log or --all-logs
|
|
* - Wait for elements: Delay capture with --wait-for selector
|
|
* - Full output mode: Enable all display options with --full
|
|
*
|
|
* DESIGN GOALS:
|
|
* - Data-driven debugging - Focus on data flow, not visual presentation
|
|
* - Minimal, terse output - No fancy formatting or colors in the output
|
|
* - Log-like format - Output designed to be easily parsed or grepped
|
|
* - Real browser testing - Tests the full stack including JavaScript
|
|
* - Development only - This tool is disabled in production environments
|
|
* - Clean slate testing - Logs rotated before/after each test
|
|
*
|
|
* USAGE EXAMPLES:
|
|
* php artisan rsx:debug /dashboard # Basic route test
|
|
* php artisan rsx:debug /dashboard --user-id=1 # Test as user ID 1
|
|
* php artisan rsx:debug /api/users --no-body # Headers only
|
|
* php artisan rsx:debug /login --full # Maximum information
|
|
* php artisan rsx:debug /api/data --xhr-list # Simple XHR list
|
|
* php artisan rsx:debug /api/data --xhr-dump # Full XHR details
|
|
* php artisan rsx:debug /form --expect-element="#submit" # Verify element exists
|
|
* php artisan rsx:debug /page --dump-element=".content" # Extract element HTML
|
|
* php artisan rsx:debug /app --storage # View storage data
|
|
* php artisan rsx:debug /form --input-elements # List form inputs
|
|
* php artisan rsx:debug /api --post='{"key":"value"}' # POST JSON data
|
|
* php artisan rsx:debug /slow --wait-for=".loaded" # Wait for element
|
|
* php artisan rsx:debug /auth --follow-redirects # Track redirects
|
|
* php artisan rsx:debug /page --all-logs # Show all log files
|
|
* php artisan rsx:debug /demo --eval="typeof jQuery" # Execute JavaScript code
|
|
*
|
|
* OMITTED FEATURES:
|
|
* This tool is designed for data-driven debugging, not visual testing or interaction.
|
|
* The following features are intentionally omitted as out of scope:
|
|
*
|
|
* - Screenshot capture: Not implemented as this tool focuses on data, not visuals
|
|
* - PDF generation: Not implemented as this tool is for debugging, not archival
|
|
* - Page interaction (click, fill, select): Out of scope for route debugging
|
|
* - Visual regression testing: Use dedicated visual testing tools instead
|
|
* - Performance profiling: Use browser DevTools or dedicated profiling tools
|
|
* - Accessibility testing: Use dedicated accessibility testing tools
|
|
*
|
|
* These omissions keep the tool focused on its core purpose: debugging data flow
|
|
* through routes, not testing UI appearance or user interactions.
|
|
*
|
|
* IMPLEMENTATION DETAILS:
|
|
* - Uses X-Playwright-Test header to trigger plain text error responses
|
|
* - Uses X-Dev-Auth-User-Id header for backdoor authentication
|
|
* - Auto-installs Playwright and Chromium if not present
|
|
* - Route interception prevents CORS issues with CDN resources
|
|
* - Works with both Laravel routes and RSX routes
|
|
* - Logs rotated via Debugger::logrotate() for clean testing
|
|
*
|
|
* SECURITY:
|
|
* - Only available in local/development/testing environments
|
|
* - Throws fatal error if attempted in production
|
|
* - Backdoor authentication only works in non-production environments
|
|
*
|
|
* OUTPUT FORMAT:
|
|
* The command outputs in a simple, parseable format:
|
|
* - Status line with route and response code
|
|
* - Redirect chain (if --follow-redirects used)
|
|
* - Response headers (if --headers used)
|
|
* - Console errors (always shown if present)
|
|
* - Console logs (if --console-log used)
|
|
* - XHR/fetch requests (if --xhr-dump or --xhr-list used)
|
|
* - Input elements (if --input-elements used)
|
|
* - Cookies (if --cookies used)
|
|
* - Storage data (if --storage used)
|
|
* - Element HTML (if --dump-element used)
|
|
* - Response body (unless --no-body used)
|
|
* - Laravel log errors (shown by default if errors exist)
|
|
* - Nginx error log (shown by default if errors exist)
|
|
* - All logs complete (if --all-logs used)
|
|
*
|
|
* The --full flag enables all display options except --no-body and --follow-redirects,
|
|
* providing maximum diagnostic information in a single command.
|
|
*/
|
|
class Route_Debug_Command extends Command
|
|
{
|
|
/**
|
|
* The name and signature of the console command.
|
|
*
|
|
* @var string
|
|
*/
|
|
protected $signature = 'rsx:debug
|
|
{url? : The URL to debug (e.g., /dashboard, /api/users). Use --examples to see usage examples}
|
|
{--examples : Show comprehensive usage examples}
|
|
{--user= : Test as specific user ID (bypasses authentication)}
|
|
{--user-id= : Alias for --user option}
|
|
{--log : Display Laravel error log if not empty}
|
|
{--no-body : Suppress HTTP response body (show headers/status only)}
|
|
{--follow-redirects : Follow HTTP redirects and show full redirect chain}
|
|
{--headers : Display all HTTP response headers}
|
|
{--console-log : Display all browser console output (not just errors) and console_debug() output even if SHOW_CONSOLE_DEBUG_HTTP=false}
|
|
{--xhr-dump : Capture full details of XHR/fetch requests (URL, headers, body, response)}
|
|
{--input-elements : List all form input elements with values and attributes}
|
|
{--post= : Send POST request with JSON data (e.g., --post=\'{"key":"value"}\')}
|
|
{--cookies : Display all browser cookies with domains and expiry}
|
|
{--wait-for= : Wait for CSS selector before capture (e.g., --wait-for=".loaded")}
|
|
{--all-logs : Display Laravel log and nginx logs after test}
|
|
{--expect-element= : Verify element exists by CSS selector (fails if not found)}
|
|
{--dump-element= : Extract and display HTML of element by CSS selector}
|
|
{--storage : Display localStorage and sessionStorage contents}
|
|
{--xhr-list : Show simple list of XHR/fetch URLs and status codes}
|
|
{--full : Enable all display options except no-body and follow-redirects}
|
|
{--eval= : Execute JavaScript code in the page context and display the result}
|
|
{--timeout= : Navigation timeout in milliseconds (minimum 30000ms, default 30000ms)}
|
|
{--console-debug-filter= : Filter console_debug output to specific channel (e.g., BENCHMARK, DISPATCH)}
|
|
{--console-debug-benchmark : Include benchmark timing prefixes in console_debug output}
|
|
{--console-debug-all : Show all console_debug channels (overrides filter)}
|
|
{--console-debug-disable : Disable console_debug entirely for this test}
|
|
{--console-list : Alias for --console-log to display all console output}';
|
|
|
|
/**
|
|
* The console command description.
|
|
*
|
|
* @var string
|
|
*/
|
|
protected $description = 'Debug URLs using headless browser - captures response, console, XHR, DOM state, storage, and logs (development only)';
|
|
|
|
/**
|
|
* Execute the console command.
|
|
*/
|
|
public function handle()
|
|
{
|
|
// Check environment - throw fatal error in production
|
|
if (app()->environment('production')) {
|
|
throw new \RuntimeException('FATAL: rsx:debug command is not available in production environment. This is a development-only debugging tool.');
|
|
}
|
|
|
|
// Check if --examples was requested
|
|
if ($this->option('examples')) {
|
|
$this->showExamples();
|
|
return 0;
|
|
}
|
|
|
|
// Get the URL to debug
|
|
$url = $this->argument('url');
|
|
|
|
// If no URL provided, show help
|
|
if (!$url) {
|
|
$this->error('No URL provided. Use --examples to see usage examples.');
|
|
return 1;
|
|
}
|
|
|
|
// Check if console_debug is disabled globally and user didn't override
|
|
$console_debug_enabled = config('rsx.console_debug.enabled', false) || env('CONSOLE_DEBUG_ENABLED') === 'true';
|
|
$console_debug_override = $this->option('console-log') ||
|
|
$this->option('console-list') ||
|
|
$this->option('console-debug-all') ||
|
|
$this->option('console-debug-filter') ||
|
|
$this->option('console-debug-benchmark') ||
|
|
env('CONSOLE_DEBUG_FILTER') ||
|
|
env('CONSOLE_DEBUG_BENCHMARK');
|
|
$console_debug_disabled = $this->option('console-debug-disable') || env('CONSOLE_DEBUG_ENABLED') === 'false';
|
|
|
|
// If console_debug is disabled and not overridden, show a single line message
|
|
if (!$console_debug_enabled && !$console_debug_override && !$console_debug_disabled) {
|
|
$this->line('console_debug is disabled. Run `php artisan rsx:man console_debug` for more information on its usage.');
|
|
// Don't return early - still run the test, just with the message
|
|
}
|
|
|
|
// Ensure URL starts with /
|
|
if (!str_starts_with($url, '/')) {
|
|
$url = '/' . $url;
|
|
}
|
|
|
|
// Get user ID from options
|
|
$user_id = $this->option('user-id') ?: $this->option('user');
|
|
|
|
// Get log flag
|
|
$show_log = $this->option('log');
|
|
|
|
// Get no-body flag
|
|
$no_body = $this->option('no-body');
|
|
|
|
// Get follow-redirects flag
|
|
$follow_redirects = $this->option('follow-redirects');
|
|
|
|
// Get headers flag
|
|
$headers = $this->option('headers');
|
|
|
|
// Get console-log flag
|
|
$console_log = $this->option('console-log');
|
|
|
|
// Get xhr-dump flag
|
|
$xhr_dump = $this->option('xhr-dump');
|
|
|
|
// Get input-elements flag
|
|
$input_elements = $this->option('input-elements');
|
|
|
|
// Get POST data
|
|
$post_data = $this->option('post');
|
|
|
|
// Get cookies flag
|
|
$cookies = $this->option('cookies');
|
|
|
|
// Get wait-for selector
|
|
$wait_for = $this->option('wait-for');
|
|
|
|
// Get all-logs flag
|
|
$all_logs = $this->option('all-logs');
|
|
|
|
// Get new feature flags
|
|
$expect_element = $this->option('expect-element');
|
|
$dump_element = $this->option('dump-element');
|
|
$storage = $this->option('storage');
|
|
$xhr_list = $this->option('xhr-list');
|
|
$full = $this->option('full');
|
|
$eval_code = $this->option('eval');
|
|
|
|
// Get timeout option and validate
|
|
$timeout = $this->option('timeout');
|
|
if ($timeout !== null) {
|
|
$timeout = intval($timeout);
|
|
if ($timeout < 30000) {
|
|
$this->error('❌ Timeout value is in milliseconds and must be no less than 30000 milliseconds (30 seconds)');
|
|
return 1;
|
|
}
|
|
} else {
|
|
$timeout = 30000; // Default 30 seconds
|
|
}
|
|
|
|
// Get console debug options (with environment variable fallbacks)
|
|
$console_debug_filter = $this->option('console-debug-filter') ?: env('CONSOLE_DEBUG_FILTER');
|
|
$console_debug_benchmark = $this->option('console-debug-benchmark') ?: env('CONSOLE_DEBUG_BENCHMARK', false);
|
|
$console_debug_all = $this->option('console-debug-all') ?: (env('CONSOLE_DEBUG_FILTER') === 'ALL');
|
|
$console_debug_disable = $this->option('console-debug-disable') ?: (env('CONSOLE_DEBUG_ENABLED') === 'false');
|
|
|
|
// Auto-enable console-log and console_debug when console-debug-filter is set
|
|
if ($console_debug_filter && !$console_debug_disable) {
|
|
$console_log = true; // Enable console log output
|
|
// console_debug is enabled via the filter itself
|
|
}
|
|
|
|
// Auto-enable console_debug when CONSOLE_DEBUG_ENABLED=true
|
|
if (env('CONSOLE_DEBUG_ENABLED') === 'true' && !$console_debug_disable) {
|
|
// Enable console output if not explicitly disabled
|
|
if (!$console_debug_filter && !$console_debug_all) {
|
|
$console_debug_all = true; // Show all channels if no specific filter
|
|
}
|
|
}
|
|
$console_list = $this->option('console-list');
|
|
|
|
// console-list is an alias for console-log
|
|
if ($console_list) {
|
|
$console_log = true;
|
|
}
|
|
|
|
// Rotate logs before test to ensure clean slate
|
|
Debugger::logrotate();
|
|
|
|
// Check if Playwright script exists
|
|
$playwright_script = base_path('bin/route-debug.js');
|
|
if (!file_exists($playwright_script)) {
|
|
$this->error("❌ Playwright script not found: {$playwright_script}");
|
|
$this->error('Please create the script or check your installation');
|
|
return 1;
|
|
}
|
|
|
|
// Check if node/npm is available
|
|
$node_check = new Process(['node', '--version']);
|
|
$node_check->run();
|
|
|
|
if (!$node_check->isSuccessful()) {
|
|
$this->error('❌ Node.js is not installed or not in PATH');
|
|
return 1;
|
|
}
|
|
|
|
// Check if playwright is installed
|
|
$playwright_check = new Process(['node', '-e', "require('playwright')"], base_path());
|
|
$playwright_check->run();
|
|
|
|
if (!$playwright_check->isSuccessful()) {
|
|
$this->warn('⚠️ Playwright not installed. Installing now...');
|
|
$npm_install = new Process(['npm', 'install', 'playwright'], base_path());
|
|
$npm_install->run(function ($type, $buffer) {
|
|
echo $buffer;
|
|
});
|
|
|
|
if (!$npm_install->isSuccessful()) {
|
|
$this->error('❌ Failed to install Playwright');
|
|
return 1;
|
|
}
|
|
$this->info('✅ Playwright installed');
|
|
$this->info('');
|
|
}
|
|
|
|
// Check if chromium browser is installed and up to date
|
|
$browser_check_script = "const {chromium} = require('playwright'); chromium.launch({headless:true}).then(b => {b.close(); process.exit(0);}).catch(e => {console.error(e.message); process.exit(1);});";
|
|
$browser_check = new Process(['node', '-e', $browser_check_script], base_path(), $_ENV, null, 10);
|
|
$browser_check->run();
|
|
|
|
if (!$browser_check->isSuccessful()) {
|
|
$error_output = $browser_check->getErrorOutput() . $browser_check->getOutput();
|
|
|
|
// Check if it's a browser not installed or out of date error
|
|
if (str_contains($error_output, "Executable doesn't exist") ||
|
|
str_contains($error_output, "browserType.launch") ||
|
|
str_contains($error_output, "Playwright was just installed or updated")) {
|
|
|
|
$this->info('Installing/updating Chromium browser...');
|
|
$browser_install = new Process(['npx', 'playwright', 'install', 'chromium'], base_path());
|
|
$browser_install->setTimeout(300); // 5 minute timeout for download
|
|
$browser_install->run(function ($type, $buffer) {
|
|
// Silent - downloads can be verbose
|
|
});
|
|
|
|
if (!$browser_install->isSuccessful()) {
|
|
$this->error('❌ Failed to install Chromium browser');
|
|
$this->error('Run manually: npx playwright install chromium');
|
|
return 1;
|
|
}
|
|
$this->info('✅ Chromium browser installed/updated');
|
|
$this->info('');
|
|
} else {
|
|
$this->error('❌ Browser check failed: ' . trim($error_output));
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
// Build command arguments
|
|
$command_args = ['node', $playwright_script, $url];
|
|
|
|
if ($user_id) {
|
|
$command_args[] = "--user-id={$user_id}";
|
|
}
|
|
|
|
if ($show_log) {
|
|
$command_args[] = '--log';
|
|
}
|
|
|
|
if ($no_body) {
|
|
$command_args[] = '--no-body';
|
|
}
|
|
|
|
if ($follow_redirects) {
|
|
$command_args[] = '--follow-redirects';
|
|
}
|
|
|
|
if ($headers) {
|
|
$command_args[] = '--headers';
|
|
}
|
|
|
|
if ($console_log) {
|
|
$command_args[] = '--console-log';
|
|
}
|
|
|
|
if ($xhr_dump) {
|
|
$command_args[] = '--xhr-dump';
|
|
}
|
|
|
|
if ($input_elements) {
|
|
$command_args[] = '--input-elements';
|
|
}
|
|
|
|
if ($post_data) {
|
|
$command_args[] = "--post={$post_data}";
|
|
}
|
|
|
|
if ($cookies) {
|
|
$command_args[] = '--cookies';
|
|
}
|
|
|
|
if ($wait_for) {
|
|
$command_args[] = "--wait-for={$wait_for}";
|
|
}
|
|
|
|
if ($all_logs) {
|
|
$command_args[] = '--all-logs';
|
|
}
|
|
|
|
if ($expect_element) {
|
|
$command_args[] = "--expect-element={$expect_element}";
|
|
}
|
|
|
|
if ($dump_element) {
|
|
$command_args[] = "--dump-element={$dump_element}";
|
|
}
|
|
|
|
if ($storage) {
|
|
$command_args[] = '--storage';
|
|
}
|
|
|
|
if ($xhr_list) {
|
|
$command_args[] = '--xhr-list';
|
|
}
|
|
|
|
if ($full) {
|
|
$command_args[] = '--full';
|
|
}
|
|
|
|
if ($eval_code) {
|
|
// Don't use escapeshellarg here as it adds extra quotes
|
|
// Just pass the eval code directly since Process class handles escaping
|
|
$command_args[] = "--eval={$eval_code}";
|
|
}
|
|
|
|
if ($timeout) {
|
|
$command_args[] = "--timeout={$timeout}";
|
|
}
|
|
|
|
if ($console_debug_filter) {
|
|
$command_args[] = "--console-debug-filter={$console_debug_filter}";
|
|
}
|
|
|
|
if ($console_debug_benchmark) {
|
|
$command_args[] = "--console-debug-benchmark";
|
|
}
|
|
|
|
if ($console_debug_all) {
|
|
$command_args[] = "--console-debug-all";
|
|
}
|
|
|
|
if ($console_debug_disable) {
|
|
$command_args[] = "--console-debug-disable";
|
|
}
|
|
|
|
// Pass Laravel log path as environment variable
|
|
$laravel_log_path = storage_path('logs/laravel.log');
|
|
|
|
$env = array_merge($_ENV, [
|
|
'LARAVEL_LOG_PATH' => $laravel_log_path
|
|
]);
|
|
|
|
// Add console debug filter to environment if provided
|
|
if ($console_debug_filter) {
|
|
$env['CONSOLE_DEBUG_FILTER'] = $console_debug_filter;
|
|
$env['CONSOLE_DEBUG_ENABLED'] = 'true'; // Enable console_debug when filter is set
|
|
}
|
|
|
|
// Convert timeout from milliseconds to seconds for Process timeout
|
|
// Add 10 seconds buffer to the Process timeout to allow Playwright to timeout first
|
|
$process_timeout = ($timeout / 1000) + 10;
|
|
|
|
// Release the application lock before running Playwright to prevent lock contention
|
|
// The artisan command holds a WRITE lock which would block the web request's READ lock
|
|
\App\RSpade\Core\Bootstrap\RsxBootstrap::temporarily_release_lock();
|
|
|
|
$process = new Process(
|
|
$command_args,
|
|
base_path(),
|
|
$env,
|
|
null,
|
|
$process_timeout
|
|
);
|
|
|
|
$process->run(function ($type, $buffer) {
|
|
// Output directly to console
|
|
echo $buffer;
|
|
});
|
|
|
|
// Rotate logs after test to clean slate for next run
|
|
Debugger::logrotate();
|
|
|
|
return $process->isSuccessful() ? 0 : 1;
|
|
}
|
|
|
|
/**
|
|
* Show comprehensive usage examples
|
|
*/
|
|
protected function showExamples()
|
|
{
|
|
$this->info('RSX Debug Command - Comprehensive Usage Examples');
|
|
$this->line('=================================================');
|
|
$this->line('');
|
|
|
|
$this->comment('BASIC USAGE:');
|
|
$this->line(' php artisan rsx:debug /dashboard # Test a URL');
|
|
$this->line(' php artisan rsx:debug /api/users --no-body # Headers only');
|
|
$this->line(' php artisan rsx:debug /login --full # All information');
|
|
$this->line('');
|
|
|
|
$this->comment('AUTHENTICATION:');
|
|
$this->line(' php artisan rsx:debug /admin --user=1 # Test as user ID 1');
|
|
$this->line(' php artisan rsx:debug /profile --user-id=5 # Alternative syntax');
|
|
$this->line('');
|
|
|
|
$this->comment('TESTING RSX JAVASCRIPT:');
|
|
$this->line(' php artisan rsx:debug /demo --eval="Rsx.Route(\'Demo_Controller\').url()" --no-body');
|
|
$this->line(' php artisan rsx:debug /demo --eval="JSON.stringify(Rsx._routes)" --no-body');
|
|
$this->line(' php artisan rsx:debug /demo --eval="Rsx.is_dev()" --no-body');
|
|
$this->line('');
|
|
|
|
$this->comment('DEBUGGING OUTPUT:');
|
|
$this->line(' php artisan rsx:debug / --console-log # All console output');
|
|
$this->line(' php artisan rsx:debug / --console-debug-filter=AUTH # Filter console_debug');
|
|
$this->line(' php artisan rsx:debug / --console-debug-benchmark # With timing');
|
|
$this->line(' php artisan rsx:debug / --all-logs # Show all log files');
|
|
$this->line('');
|
|
|
|
$this->comment('XHR/AJAX MONITORING:');
|
|
$this->line(' php artisan rsx:debug /api --xhr-list # Simple XHR list');
|
|
$this->line(' php artisan rsx:debug /api --xhr-dump # Full XHR details');
|
|
$this->line('');
|
|
|
|
$this->comment('DOM INSPECTION:');
|
|
$this->line(' php artisan rsx:debug /form --expect-element="#submit" # Verify element exists');
|
|
$this->line(' php artisan rsx:debug /page --dump-element=".content" # Extract element HTML');
|
|
$this->line(' php artisan rsx:debug /form --input-elements # List form inputs');
|
|
$this->line(' php artisan rsx:debug /slow --wait-for=".loaded" # Wait for element');
|
|
$this->line('');
|
|
|
|
$this->comment('HTTP TESTING:');
|
|
$this->line(' php artisan rsx:debug /api --post=\'{"key":"value"}\' # POST JSON data');
|
|
$this->line(' php artisan rsx:debug /auth --follow-redirects # Track redirects');
|
|
$this->line(' php artisan rsx:debug /api --headers # Display all headers');
|
|
$this->line(' php artisan rsx:debug /app --cookies # Show all cookies');
|
|
$this->line('');
|
|
|
|
$this->comment('BROWSER STATE:');
|
|
$this->line(' php artisan rsx:debug /app --storage # View localStorage/sessionStorage');
|
|
$this->line(' php artisan rsx:debug /slow --timeout=60000 # 60 second timeout');
|
|
$this->line('');
|
|
|
|
$this->comment('IMPORTANT NOTES:');
|
|
$this->line(' • When using rsx:debug with grep and no output appears, re-run without grep');
|
|
$this->line(' to see the full context and any errors that may have occurred');
|
|
$this->line(' • Use rsx_dump_die() in your code for temporary debugging output');
|
|
$this->line(' • This command is development-only and disabled in production');
|
|
$this->line(' • For more details on console_debug: php artisan rsx:man console_debug');
|
|
$this->line(' • For config options: php artisan rsx:man config_rsx');
|
|
}
|
|
} |