Add commands for dealing with cache and site data, cookies, etc

This commit is contained in:
Josh at WLTechBlog
2025-09-30 08:00:30 -05:00
parent 74d99db629
commit 72d4a5653d
10 changed files with 1553 additions and 1 deletions

View File

@@ -89,6 +89,12 @@ cremote <command> [options]
- `switch-iframe`: Switch to iframe context for subsequent commands
- `switch-main`: Switch back to main page context
- `list-tabs`: List all open tabs
- `disable-cache`: Disable browser cache for a tab
- `enable-cache`: Enable browser cache for a tab
- `clear-cache`: Clear browser cache for a tab
- `clear-all-site-data`: Clear all site data (cookies, storage, cache, etc.)
- `clear-cookies`: Clear cookies for a tab
- `clear-storage`: Clear web storage (localStorage, sessionStorage, etc.)
- `status`: Check if the daemon is running
### Current Tab Feature
@@ -304,6 +310,43 @@ cremote list-tabs
This will display all open tabs with their IDs and URLs. The current tab is marked with an asterisk (*)
#### Cache and Site Data Management
You can control browser cache and site data for testing, performance optimization, and privacy:
```bash
# Cache Management
# Disable cache for current tab (useful for testing)
cremote disable-cache [--tab="<tab-id>"] [--timeout=5]
# Enable cache for current tab
cremote enable-cache [--tab="<tab-id>"] [--timeout=5]
# Clear browser cache for current tab
cremote clear-cache [--tab="<tab-id>"] [--timeout=5]
# Site Data Management
# Clear ALL site data (cookies, storage, cache, etc.)
cremote clear-all-site-data [--tab="<tab-id>"] [--timeout=10]
# Clear only cookies
cremote clear-cookies [--tab="<tab-id>"] [--timeout=5]
# Clear only web storage (localStorage, sessionStorage, IndexedDB, etc.)
cremote clear-storage [--tab="<tab-id>"] [--timeout=5]
```
**Use Cases:**
- **Testing**: Disable cache to ensure fresh page loads without cached resources
- **Performance Testing**: Clear cache to test cold load performance
- **Debugging**: Clear cache to resolve cache-related issues
- **Development**: Disable cache during development to see changes immediately
- **Authentication Testing**: Clear cookies to test login/logout flows
- **Privacy Testing**: Clear all site data to test clean state scenarios
- **Storage Testing**: Clear web storage to test application state management
The `--timeout` parameter specifies how many seconds to wait for the operation to complete (default: 5 seconds, use longer timeouts for comprehensive data clearing).
### Connecting to a Remote Daemon
By default, the client connects to a daemon running on localhost. To connect to a daemon running on a different host:

View File

@@ -2453,3 +2453,171 @@ func (c *Client) ManageFiles(operation, pattern, maxAge string) (*FileManagement
return &result, nil
}
// DisableCache disables browser cache for a tab
// If tabID is empty, the current tab will be used
// timeout is in seconds, 0 means no timeout
func (c *Client) DisableCache(tabID string, timeout int) error {
params := map[string]string{}
// Only include tab ID if it's provided
if tabID != "" {
params["tab"] = tabID
}
// Add timeout if specified
if timeout > 0 {
params["timeout"] = strconv.Itoa(timeout)
}
resp, err := c.SendCommand("disable-cache", params)
if err != nil {
return err
}
if !resp.Success {
return fmt.Errorf("failed to disable cache: %s", resp.Error)
}
return nil
}
// EnableCache enables browser cache for a tab
// If tabID is empty, the current tab will be used
// timeout is in seconds, 0 means no timeout
func (c *Client) EnableCache(tabID string, timeout int) error {
params := map[string]string{}
// Only include tab ID if it's provided
if tabID != "" {
params["tab"] = tabID
}
// Add timeout if specified
if timeout > 0 {
params["timeout"] = strconv.Itoa(timeout)
}
resp, err := c.SendCommand("enable-cache", params)
if err != nil {
return err
}
if !resp.Success {
return fmt.Errorf("failed to enable cache: %s", resp.Error)
}
return nil
}
// ClearCache clears browser cache for a tab
// If tabID is empty, the current tab will be used
// timeout is in seconds, 0 means no timeout
func (c *Client) ClearCache(tabID string, timeout int) error {
params := map[string]string{}
// Only include tab ID if it's provided
if tabID != "" {
params["tab"] = tabID
}
// Add timeout if specified
if timeout > 0 {
params["timeout"] = strconv.Itoa(timeout)
}
resp, err := c.SendCommand("clear-cache", params)
if err != nil {
return err
}
if !resp.Success {
return fmt.Errorf("failed to clear cache: %s", resp.Error)
}
return nil
}
// ClearAllSiteData clears all site data including cookies, storage, cache, etc. for a tab
// If tabID is empty, the current tab will be used
// timeout is in seconds, 0 means no timeout
func (c *Client) ClearAllSiteData(tabID string, timeout int) error {
params := map[string]string{}
// Only include tab ID if it's provided
if tabID != "" {
params["tab"] = tabID
}
// Add timeout if specified
if timeout > 0 {
params["timeout"] = strconv.Itoa(timeout)
}
resp, err := c.SendCommand("clear-all-site-data", params)
if err != nil {
return err
}
if !resp.Success {
return fmt.Errorf("failed to clear all site data: %s", resp.Error)
}
return nil
}
// ClearCookies clears cookies for a tab
// If tabID is empty, the current tab will be used
// timeout is in seconds, 0 means no timeout
func (c *Client) ClearCookies(tabID string, timeout int) error {
params := map[string]string{}
// Only include tab ID if it's provided
if tabID != "" {
params["tab"] = tabID
}
// Add timeout if specified
if timeout > 0 {
params["timeout"] = strconv.Itoa(timeout)
}
resp, err := c.SendCommand("clear-cookies", params)
if err != nil {
return err
}
if !resp.Success {
return fmt.Errorf("failed to clear cookies: %s", resp.Error)
}
return nil
}
// ClearStorage clears web storage (localStorage, sessionStorage, IndexedDB, etc.) for a tab
// If tabID is empty, the current tab will be used
// timeout is in seconds, 0 means no timeout
func (c *Client) ClearStorage(tabID string, timeout int) error {
params := map[string]string{}
// Only include tab ID if it's provided
if tabID != "" {
params["tab"] = tabID
}
// Add timeout if specified
if timeout > 0 {
params["timeout"] = strconv.Itoa(timeout)
}
resp, err := c.SendCommand("clear-storage", params)
if err != nil {
return err
}
if !resp.Success {
return fmt.Errorf("failed to clear storage: %s", resp.Error)
}
return nil
}

BIN
daemon/cremotedaemon Executable file

Binary file not shown.

View File

@@ -1035,6 +1035,120 @@ func (d *Daemon) handleCommand(w http.ResponseWriter, r *http.Request) {
response = Response{Success: true, Data: result}
}
case "disable-cache":
tabID := cmd.Params["tab"]
timeoutStr := cmd.Params["timeout"]
// Parse timeout (default to 5 seconds if not specified)
timeout := 5
if timeoutStr != "" {
if parsedTimeout, err := strconv.Atoi(timeoutStr); err == nil && parsedTimeout > 0 {
timeout = parsedTimeout
}
}
err := d.setCacheDisabled(tabID, true, timeout)
if err != nil {
response = Response{Success: false, Error: err.Error()}
} else {
response = Response{Success: true}
}
case "enable-cache":
tabID := cmd.Params["tab"]
timeoutStr := cmd.Params["timeout"]
// Parse timeout (default to 5 seconds if not specified)
timeout := 5
if timeoutStr != "" {
if parsedTimeout, err := strconv.Atoi(timeoutStr); err == nil && parsedTimeout > 0 {
timeout = parsedTimeout
}
}
err := d.setCacheDisabled(tabID, false, timeout)
if err != nil {
response = Response{Success: false, Error: err.Error()}
} else {
response = Response{Success: true}
}
case "clear-cache":
tabID := cmd.Params["tab"]
timeoutStr := cmd.Params["timeout"]
// Parse timeout (default to 5 seconds if not specified)
timeout := 5
if timeoutStr != "" {
if parsedTimeout, err := strconv.Atoi(timeoutStr); err == nil && parsedTimeout > 0 {
timeout = parsedTimeout
}
}
err := d.clearBrowserCache(tabID, timeout)
if err != nil {
response = Response{Success: false, Error: err.Error()}
} else {
response = Response{Success: true}
}
case "clear-all-site-data":
tabID := cmd.Params["tab"]
timeoutStr := cmd.Params["timeout"]
// Parse timeout (default to 5 seconds if not specified)
timeout := 5
if timeoutStr != "" {
if parsedTimeout, err := strconv.Atoi(timeoutStr); err == nil && parsedTimeout > 0 {
timeout = parsedTimeout
}
}
err := d.clearAllSiteData(tabID, timeout)
if err != nil {
response = Response{Success: false, Error: err.Error()}
} else {
response = Response{Success: true}
}
case "clear-cookies":
tabID := cmd.Params["tab"]
timeoutStr := cmd.Params["timeout"]
// Parse timeout (default to 5 seconds if not specified)
timeout := 5
if timeoutStr != "" {
if parsedTimeout, err := strconv.Atoi(timeoutStr); err == nil && parsedTimeout > 0 {
timeout = parsedTimeout
}
}
err := d.clearCookies(tabID, timeout)
if err != nil {
response = Response{Success: false, Error: err.Error()}
} else {
response = Response{Success: true}
}
case "clear-storage":
tabID := cmd.Params["tab"]
timeoutStr := cmd.Params["timeout"]
// Parse timeout (default to 5 seconds if not specified)
timeout := 5
if timeoutStr != "" {
if parsedTimeout, err := strconv.Atoi(timeoutStr); err == nil && parsedTimeout > 0 {
timeout = parsedTimeout
}
}
err := d.clearStorage(tabID, timeout)
if err != nil {
response = Response{Success: false, Error: err.Error()}
} else {
response = Response{Success: true}
}
default:
d.debugLog("Unknown action: %s", cmd.Action)
response = Response{Success: false, Error: "Unknown action"}
@@ -5271,3 +5385,289 @@ func (d *Daemon) queryAccessibilityTree(tabID, selector, accessibleName, role st
d.debugLog("Successfully queried accessibility tree with %d matching nodes for tab: %s", len(axResult.Nodes), tabID)
return &axResult, nil
}
// setCacheDisabled enables or disables browser cache for a tab
func (d *Daemon) setCacheDisabled(tabID string, disabled bool, timeout int) error {
d.debugLog("Setting cache disabled=%v for tab: %s with timeout: %d", disabled, tabID, timeout)
// Use current tab if not specified
if tabID == "" {
tabID = d.currentTab
}
if tabID == "" {
return fmt.Errorf("no tab specified and no current tab available")
}
page, err := d.getTab(tabID)
if err != nil {
return fmt.Errorf("failed to get page: %v", err)
}
// Create a context with timeout if specified
if timeout > 0 {
ctx, cancel := context.WithTimeout(context.Background(), time.Duration(timeout)*time.Second)
defer cancel()
// Create a channel to signal completion
done := make(chan error, 1)
// Execute the cache setting in a goroutine
go func() {
err := proto.NetworkSetCacheDisabled{CacheDisabled: disabled}.Call(page)
done <- err
}()
// Wait for completion or timeout
select {
case err := <-done:
if err != nil {
return fmt.Errorf("failed to set cache disabled: %v", err)
}
case <-ctx.Done():
return fmt.Errorf("timeout setting cache disabled after %d seconds", timeout)
}
} else {
// No timeout - execute directly
err := proto.NetworkSetCacheDisabled{CacheDisabled: disabled}.Call(page)
if err != nil {
return fmt.Errorf("failed to set cache disabled: %v", err)
}
}
d.debugLog("Successfully set cache disabled=%v for tab: %s", disabled, tabID)
return nil
}
// clearBrowserCache clears the browser cache for a tab
func (d *Daemon) clearBrowserCache(tabID string, timeout int) error {
d.debugLog("Clearing browser cache for tab: %s with timeout: %d", tabID, timeout)
// Use current tab if not specified
if tabID == "" {
tabID = d.currentTab
}
if tabID == "" {
return fmt.Errorf("no tab specified and no current tab available")
}
page, err := d.getTab(tabID)
if err != nil {
return fmt.Errorf("failed to get page: %v", err)
}
// Create a context with timeout if specified
if timeout > 0 {
ctx, cancel := context.WithTimeout(context.Background(), time.Duration(timeout)*time.Second)
defer cancel()
// Create a channel to signal completion
done := make(chan error, 1)
// Execute the cache clearing in a goroutine
go func() {
err := proto.NetworkClearBrowserCache{}.Call(page)
done <- err
}()
// Wait for completion or timeout
select {
case err := <-done:
if err != nil {
return fmt.Errorf("failed to clear browser cache: %v", err)
}
case <-ctx.Done():
return fmt.Errorf("timeout clearing browser cache after %d seconds", timeout)
}
} else {
// No timeout - execute directly
err := proto.NetworkClearBrowserCache{}.Call(page)
if err != nil {
return fmt.Errorf("failed to clear browser cache: %v", err)
}
}
d.debugLog("Successfully cleared browser cache for tab: %s", tabID)
return nil
}
// clearAllSiteData clears all site data including cookies, storage, cache, etc. for a tab
func (d *Daemon) clearAllSiteData(tabID string, timeout int) error {
d.debugLog("Clearing all site data for tab: %s with timeout: %d", tabID, timeout)
// Use current tab if not specified
if tabID == "" {
tabID = d.currentTab
}
if tabID == "" {
return fmt.Errorf("no tab specified and no current tab available")
}
page, err := d.getTab(tabID)
if err != nil {
return fmt.Errorf("failed to get page: %v", err)
}
// Create a context with timeout if specified
if timeout > 0 {
ctx, cancel := context.WithTimeout(context.Background(), time.Duration(timeout)*time.Second)
defer cancel()
// Create a channel to signal completion
done := make(chan error, 1)
// Execute the site data clearing in a goroutine
go func() {
// Clear all types of site data
err := proto.StorageClearDataForOrigin{
Origin: "*", // Clear for all origins
StorageTypes: "appcache,cookies,file_systems,indexeddb,local_storage,shader_cache,websql,service_workers,cache_storage",
}.Call(page)
done <- err
}()
// Wait for completion or timeout
select {
case err := <-done:
if err != nil {
return fmt.Errorf("failed to clear all site data: %v", err)
}
case <-ctx.Done():
return fmt.Errorf("timeout clearing all site data after %d seconds", timeout)
}
} else {
// No timeout - execute directly
err := proto.StorageClearDataForOrigin{
Origin: "*", // Clear for all origins
StorageTypes: "appcache,cookies,file_systems,indexeddb,local_storage,shader_cache,websql,service_workers,cache_storage",
}.Call(page)
if err != nil {
return fmt.Errorf("failed to clear all site data: %v", err)
}
}
d.debugLog("Successfully cleared all site data for tab: %s", tabID)
return nil
}
// clearCookies clears cookies for a tab
func (d *Daemon) clearCookies(tabID string, timeout int) error {
d.debugLog("Clearing cookies for tab: %s with timeout: %d", tabID, timeout)
// Use current tab if not specified
if tabID == "" {
tabID = d.currentTab
}
if tabID == "" {
return fmt.Errorf("no tab specified and no current tab available")
}
page, err := d.getTab(tabID)
if err != nil {
return fmt.Errorf("failed to get page: %v", err)
}
// Create a context with timeout if specified
if timeout > 0 {
ctx, cancel := context.WithTimeout(context.Background(), time.Duration(timeout)*time.Second)
defer cancel()
// Create a channel to signal completion
done := make(chan error, 1)
// Execute the cookie clearing in a goroutine
go func() {
// Clear cookies only
err := proto.StorageClearDataForOrigin{
Origin: "*", // Clear for all origins
StorageTypes: "cookies",
}.Call(page)
done <- err
}()
// Wait for completion or timeout
select {
case err := <-done:
if err != nil {
return fmt.Errorf("failed to clear cookies: %v", err)
}
case <-ctx.Done():
return fmt.Errorf("timeout clearing cookies after %d seconds", timeout)
}
} else {
// No timeout - execute directly
err := proto.StorageClearDataForOrigin{
Origin: "*", // Clear for all origins
StorageTypes: "cookies",
}.Call(page)
if err != nil {
return fmt.Errorf("failed to clear cookies: %v", err)
}
}
d.debugLog("Successfully cleared cookies for tab: %s", tabID)
return nil
}
// clearStorage clears web storage (localStorage, sessionStorage, IndexedDB, etc.) for a tab
func (d *Daemon) clearStorage(tabID string, timeout int) error {
d.debugLog("Clearing storage for tab: %s with timeout: %d", tabID, timeout)
// Use current tab if not specified
if tabID == "" {
tabID = d.currentTab
}
if tabID == "" {
return fmt.Errorf("no tab specified and no current tab available")
}
page, err := d.getTab(tabID)
if err != nil {
return fmt.Errorf("failed to get page: %v", err)
}
// Create a context with timeout if specified
if timeout > 0 {
ctx, cancel := context.WithTimeout(context.Background(), time.Duration(timeout)*time.Second)
defer cancel()
// Create a channel to signal completion
done := make(chan error, 1)
// Execute the storage clearing in a goroutine
go func() {
// Clear storage types (excluding cookies and cache)
err := proto.StorageClearDataForOrigin{
Origin: "*", // Clear for all origins
StorageTypes: "appcache,file_systems,indexeddb,local_storage,websql,service_workers,cache_storage",
}.Call(page)
done <- err
}()
// Wait for completion or timeout
select {
case err := <-done:
if err != nil {
return fmt.Errorf("failed to clear storage: %v", err)
}
case <-ctx.Done():
return fmt.Errorf("timeout clearing storage after %d seconds", timeout)
}
} else {
// No timeout - execute directly
err := proto.StorageClearDataForOrigin{
Origin: "*", // Clear for all origins
StorageTypes: "appcache,file_systems,indexeddb,local_storage,websql,service_workers,cache_storage",
}.Call(page)
if err != nil {
return fmt.Errorf("failed to clear storage: %v", err)
}
}
d.debugLog("Successfully cleared storage for tab: %s", tabID)
return nil
}

138
main.go
View File

@@ -35,6 +35,12 @@ func main() {
screenshotCmd := flag.NewFlagSet("screenshot", flag.ExitOnError)
statusCmd := flag.NewFlagSet("status", flag.ExitOnError)
listTabsCmd := flag.NewFlagSet("list-tabs", flag.ExitOnError)
disableCacheCmd := flag.NewFlagSet("disable-cache", flag.ExitOnError)
enableCacheCmd := flag.NewFlagSet("enable-cache", flag.ExitOnError)
clearCacheCmd := flag.NewFlagSet("clear-cache", flag.ExitOnError)
clearAllSiteDataCmd := flag.NewFlagSet("clear-all-site-data", flag.ExitOnError)
clearCookiesCmd := flag.NewFlagSet("clear-cookies", flag.ExitOnError)
clearStorageCmd := flag.NewFlagSet("clear-storage", flag.ExitOnError)
// Define flags for each subcommand
// open-tab flags
@@ -140,6 +146,42 @@ func main() {
listTabsHost := listTabsCmd.String("host", "localhost", "Daemon host")
listTabsPort := listTabsCmd.Int("port", 8989, "Daemon port")
// disable-cache flags
disableCacheTabID := disableCacheCmd.String("tab", "", "Tab ID to disable cache for (optional, uses current tab if not specified)")
disableCacheTimeout := disableCacheCmd.Int("timeout", 5, "Timeout in seconds for disabling cache")
disableCacheHost := disableCacheCmd.String("host", "localhost", "Daemon host")
disableCachePort := disableCacheCmd.Int("port", 8989, "Daemon port")
// enable-cache flags
enableCacheTabID := enableCacheCmd.String("tab", "", "Tab ID to enable cache for (optional, uses current tab if not specified)")
enableCacheTimeout := enableCacheCmd.Int("timeout", 5, "Timeout in seconds for enabling cache")
enableCacheHost := enableCacheCmd.String("host", "localhost", "Daemon host")
enableCachePort := enableCacheCmd.Int("port", 8989, "Daemon port")
// clear-cache flags
clearCacheTabID := clearCacheCmd.String("tab", "", "Tab ID to clear cache for (optional, uses current tab if not specified)")
clearCacheTimeout := clearCacheCmd.Int("timeout", 5, "Timeout in seconds for clearing cache")
clearCacheHost := clearCacheCmd.String("host", "localhost", "Daemon host")
clearCachePort := clearCacheCmd.Int("port", 8989, "Daemon port")
// clear-all-site-data flags
clearAllSiteDataTabID := clearAllSiteDataCmd.String("tab", "", "Tab ID to clear all site data for (optional, uses current tab if not specified)")
clearAllSiteDataTimeout := clearAllSiteDataCmd.Int("timeout", 5, "Timeout in seconds for clearing all site data")
clearAllSiteDataHost := clearAllSiteDataCmd.String("host", "localhost", "Daemon host")
clearAllSiteDataPort := clearAllSiteDataCmd.Int("port", 8989, "Daemon port")
// clear-cookies flags
clearCookiesTabID := clearCookiesCmd.String("tab", "", "Tab ID to clear cookies for (optional, uses current tab if not specified)")
clearCookiesTimeout := clearCookiesCmd.Int("timeout", 5, "Timeout in seconds for clearing cookies")
clearCookiesHost := clearCookiesCmd.String("host", "localhost", "Daemon host")
clearCookiesPort := clearCookiesCmd.Int("port", 8989, "Daemon port")
// clear-storage flags
clearStorageTabID := clearStorageCmd.String("tab", "", "Tab ID to clear storage for (optional, uses current tab if not specified)")
clearStorageTimeout := clearStorageCmd.Int("timeout", 5, "Timeout in seconds for clearing storage")
clearStorageHost := clearStorageCmd.String("host", "localhost", "Daemon host")
clearStoragePort := clearStorageCmd.Int("port", 8989, "Daemon port")
// Check if a subcommand is provided
if len(os.Args) < 2 {
printUsage()
@@ -490,6 +532,96 @@ func main() {
}
}
case "disable-cache":
disableCacheCmd.Parse(os.Args[2:])
// Create a client
c := client.NewClient(*disableCacheHost, *disableCachePort)
// Disable cache
err := c.DisableCache(*disableCacheTabID, *disableCacheTimeout)
if err != nil {
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
os.Exit(1)
}
fmt.Println("Cache disabled successfully")
case "enable-cache":
enableCacheCmd.Parse(os.Args[2:])
// Create a client
c := client.NewClient(*enableCacheHost, *enableCachePort)
// Enable cache
err := c.EnableCache(*enableCacheTabID, *enableCacheTimeout)
if err != nil {
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
os.Exit(1)
}
fmt.Println("Cache enabled successfully")
case "clear-cache":
clearCacheCmd.Parse(os.Args[2:])
// Create a client
c := client.NewClient(*clearCacheHost, *clearCachePort)
// Clear cache
err := c.ClearCache(*clearCacheTabID, *clearCacheTimeout)
if err != nil {
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
os.Exit(1)
}
fmt.Println("Cache cleared successfully")
case "clear-all-site-data":
clearAllSiteDataCmd.Parse(os.Args[2:])
// Create a client
c := client.NewClient(*clearAllSiteDataHost, *clearAllSiteDataPort)
// Clear all site data
err := c.ClearAllSiteData(*clearAllSiteDataTabID, *clearAllSiteDataTimeout)
if err != nil {
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
os.Exit(1)
}
fmt.Println("All site data cleared successfully")
case "clear-cookies":
clearCookiesCmd.Parse(os.Args[2:])
// Create a client
c := client.NewClient(*clearCookiesHost, *clearCookiesPort)
// Clear cookies
err := c.ClearCookies(*clearCookiesTabID, *clearCookiesTimeout)
if err != nil {
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
os.Exit(1)
}
fmt.Println("Cookies cleared successfully")
case "clear-storage":
clearStorageCmd.Parse(os.Args[2:])
// Create a client
c := client.NewClient(*clearStorageHost, *clearStoragePort)
// Clear storage
err := c.ClearStorage(*clearStorageTabID, *clearStorageTimeout)
if err != nil {
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
os.Exit(1)
}
fmt.Println("Storage cleared successfully")
default:
printUsage()
os.Exit(1)
@@ -515,6 +647,12 @@ func printUsage() {
fmt.Println(" switch-main Switch back to main page context")
fmt.Println(" screenshot Take a screenshot of the current page")
fmt.Println(" list-tabs List all open tabs")
fmt.Println(" disable-cache Disable browser cache for a tab")
fmt.Println(" enable-cache Enable browser cache for a tab")
fmt.Println(" clear-cache Clear browser cache for a tab")
fmt.Println(" clear-all-site-data Clear all site data (cookies, storage, cache, etc.)")
fmt.Println(" clear-cookies Clear cookies for a tab")
fmt.Println(" clear-storage Clear web storage (localStorage, sessionStorage, etc.)")
fmt.Println(" status Check if the daemon is running")
fmt.Println("\nRun 'cremote <command> -h' for more information on a command")
fmt.Println("\nBefore using this tool, make sure the daemon is running:")

View File

@@ -920,6 +920,120 @@ Returns file management results:
}
```
### 28. `web_disable_cache_cremotemcp` *(New in Phase 6)*
Disable browser cache for a tab.
**Parameters:**
- `tab` (optional): Tab ID (uses current tab if not specified)
- `timeout` (optional): Timeout in seconds (default: 5)
**Example Usage:**
```
# Disable cache for current tab
web_disable_cache_cremotemcp:
timeout: 10
# Disable cache for specific tab
web_disable_cache_cremotemcp:
tab: "tab-123"
timeout: 5
```
### 29. `web_enable_cache_cremotemcp` *(New in Phase 6)*
Enable browser cache for a tab.
**Parameters:**
- `tab` (optional): Tab ID (uses current tab if not specified)
- `timeout` (optional): Timeout in seconds (default: 5)
**Example Usage:**
```
# Enable cache for current tab
web_enable_cache_cremotemcp:
timeout: 10
# Enable cache for specific tab
web_enable_cache_cremotemcp:
tab: "tab-123"
timeout: 5
```
### 30. `web_clear_cache_cremotemcp` *(New in Phase 6)*
Clear browser cache for a tab.
**Parameters:**
- `tab` (optional): Tab ID (uses current tab if not specified)
- `timeout` (optional): Timeout in seconds (default: 5)
**Example Usage:**
```
# Clear cache for current tab
web_clear_cache_cremotemcp:
timeout: 10
# Clear cache for specific tab
web_clear_cache_cremotemcp:
tab: "tab-123"
timeout: 5
```
### 31. `web_clear_all_site_data_cremotemcp` *(New in Phase 6)*
Clear all site data including cookies, storage, cache, etc. for a tab.
**Parameters:**
- `tab` (optional): Tab ID (uses current tab if not specified)
- `timeout` (optional): Timeout in seconds (default: 5)
**Example Usage:**
```
# Clear all site data for current tab
web_clear_all_site_data_cremotemcp:
timeout: 15
# Clear all site data for specific tab
web_clear_all_site_data_cremotemcp:
tab: "tab-123"
timeout: 10
```
### 32. `web_clear_cookies_cremotemcp` *(New in Phase 6)*
Clear cookies for a tab.
**Parameters:**
- `tab` (optional): Tab ID (uses current tab if not specified)
- `timeout` (optional): Timeout in seconds (default: 5)
**Example Usage:**
```
# Clear cookies for current tab
web_clear_cookies_cremotemcp:
timeout: 10
# Clear cookies for specific tab
web_clear_cookies_cremotemcp:
tab: "tab-123"
timeout: 5
```
### 33. `web_clear_storage_cremotemcp` *(New in Phase 6)*
Clear web storage (localStorage, sessionStorage, IndexedDB, etc.) for a tab.
**Parameters:**
- `tab` (optional): Tab ID (uses current tab if not specified)
- `timeout` (optional): Timeout in seconds (default: 5)
**Example Usage:**
```
# Clear storage for current tab
web_clear_storage_cremotemcp:
timeout: 10
# Clear storage for specific tab
web_clear_storage_cremotemcp:
tab: "tab-123"
timeout: 5
```
## Common Usage Patterns
### 1. Basic Web Navigation

View File

@@ -533,9 +533,87 @@ Manage files (cleanup, list, get info).
Operations: `cleanup` (remove old files), `list` (list files), `info` (get file details).
#### 28. `web_disable_cache_cremotemcp`
Disable browser cache for a tab.
```json
{
"name": "web_disable_cache_cremotemcp",
"arguments": {
"tab": "tab-123",
"timeout": 5
}
}
```
#### 29. `web_enable_cache_cremotemcp`
Enable browser cache for a tab.
```json
{
"name": "web_enable_cache_cremotemcp",
"arguments": {
"tab": "tab-123",
"timeout": 5
}
}
```
#### 30. `web_clear_cache_cremotemcp`
Clear browser cache for a tab.
```json
{
"name": "web_clear_cache_cremotemcp",
"arguments": {
"tab": "tab-123",
"timeout": 5
}
}
```
#### 31. `web_clear_all_site_data_cremotemcp`
Clear all site data including cookies, storage, cache, etc. for a tab.
```json
{
"name": "web_clear_all_site_data_cremotemcp",
"arguments": {
"tab": "tab-123",
"timeout": 10
}
}
```
#### 32. `web_clear_cookies_cremotemcp`
Clear cookies for a tab.
```json
{
"name": "web_clear_cookies_cremotemcp",
"arguments": {
"tab": "tab-123",
"timeout": 5
}
}
```
#### 33. `web_clear_storage_cremotemcp`
Clear web storage (localStorage, sessionStorage, IndexedDB, etc.) for a tab.
```json
{
"name": "web_clear_storage_cremotemcp",
"arguments": {
"tab": "tab-123",
"timeout": 5
}
}
```
## 🎉 Complete Enhancement Summary
All 5 phases of the MCP enhancement plan have been successfully implemented, delivering a comprehensive web automation platform with **27 tools** organized across the following capabilities:
All 6 phases of the MCP enhancement plan have been successfully implemented, delivering a comprehensive web automation platform with **33 tools** organized across the following capabilities:
### ✅ Phase 1: Element State and Checking (2 tools)
**Enables conditional logic without timing issues**
@@ -579,6 +657,17 @@ All 5 phases of the MCP enhancement plan have been successfully implemented, del
**Benefits**: Better debugging with targeted screenshots, improved file handling workflows, automatic resource management, enhanced visual debugging capabilities.
### ✅ Phase 6: Browser Cache and Site Data Management (6 tools)
**Enables comprehensive cache and site data control for testing and privacy**
- `web_disable_cache_cremotemcp`: Disable browser cache for a tab
- `web_enable_cache_cremotemcp`: Enable browser cache for a tab
- `web_clear_cache_cremotemcp`: Clear browser cache for a tab
- `web_clear_all_site_data_cremotemcp`: Clear all site data (cookies, storage, cache, etc.)
- `web_clear_cookies_cremotemcp`: Clear cookies for a tab
- `web_clear_storage_cremotemcp`: Clear web storage (localStorage, sessionStorage, IndexedDB, etc.)
**Benefits**: Essential for testing scenarios requiring fresh page loads, performance testing without cached resources, debugging cache-related issues, ensuring consistent test environments, privacy testing, authentication testing, and complete site data cleanup.
## Key Benefits for LLM Agents
### 🚀 **Efficiency Gains**

View File

@@ -2168,6 +2168,278 @@ func main() {
}, nil
})
// Cache management tools
mcpServer.AddTool(mcp.Tool{
Name: "web_disable_cache_cremotemcp",
Description: "Disable browser cache for a tab",
InputSchema: mcp.ToolInputSchema{
Type: "object",
Properties: map[string]any{
"tab": map[string]any{
"type": "string",
"description": "Tab ID (optional, uses current tab)",
},
"timeout": map[string]any{
"type": "integer",
"description": "Timeout in seconds (default: 5)",
"default": 5,
},
},
},
}, func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
// Convert arguments to map
params, ok := request.Params.Arguments.(map[string]any)
if !ok {
return nil, fmt.Errorf("invalid arguments format")
}
tab := getStringParam(params, "tab", "")
timeout := getIntParam(params, "timeout", 5)
err := cremoteServer.client.DisableCache(tab, timeout)
if err != nil {
return &mcp.CallToolResult{
Content: []mcp.Content{
mcp.NewTextContent(fmt.Sprintf("Error disabling cache: %v", err)),
},
IsError: true,
}, nil
}
return &mcp.CallToolResult{
Content: []mcp.Content{
mcp.NewTextContent("Cache disabled successfully"),
},
IsError: false,
}, nil
})
mcpServer.AddTool(mcp.Tool{
Name: "web_enable_cache_cremotemcp",
Description: "Enable browser cache for a tab",
InputSchema: mcp.ToolInputSchema{
Type: "object",
Properties: map[string]any{
"tab": map[string]any{
"type": "string",
"description": "Tab ID (optional, uses current tab)",
},
"timeout": map[string]any{
"type": "integer",
"description": "Timeout in seconds (default: 5)",
"default": 5,
},
},
},
}, func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
// Convert arguments to map
params, ok := request.Params.Arguments.(map[string]any)
if !ok {
return nil, fmt.Errorf("invalid arguments format")
}
tab := getStringParam(params, "tab", "")
timeout := getIntParam(params, "timeout", 5)
err := cremoteServer.client.EnableCache(tab, timeout)
if err != nil {
return &mcp.CallToolResult{
Content: []mcp.Content{
mcp.NewTextContent(fmt.Sprintf("Error enabling cache: %v", err)),
},
IsError: true,
}, nil
}
return &mcp.CallToolResult{
Content: []mcp.Content{
mcp.NewTextContent("Cache enabled successfully"),
},
IsError: false,
}, nil
})
mcpServer.AddTool(mcp.Tool{
Name: "web_clear_cache_cremotemcp",
Description: "Clear browser cache for a tab",
InputSchema: mcp.ToolInputSchema{
Type: "object",
Properties: map[string]any{
"tab": map[string]any{
"type": "string",
"description": "Tab ID (optional, uses current tab)",
},
"timeout": map[string]any{
"type": "integer",
"description": "Timeout in seconds (default: 5)",
"default": 5,
},
},
},
}, func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
// Convert arguments to map
params, ok := request.Params.Arguments.(map[string]any)
if !ok {
return nil, fmt.Errorf("invalid arguments format")
}
tab := getStringParam(params, "tab", "")
timeout := getIntParam(params, "timeout", 5)
err := cremoteServer.client.ClearCache(tab, timeout)
if err != nil {
return &mcp.CallToolResult{
Content: []mcp.Content{
mcp.NewTextContent(fmt.Sprintf("Error clearing cache: %v", err)),
},
IsError: true,
}, nil
}
return &mcp.CallToolResult{
Content: []mcp.Content{
mcp.NewTextContent("Cache cleared successfully"),
},
IsError: false,
}, nil
})
// Site data management tools
mcpServer.AddTool(mcp.Tool{
Name: "web_clear_all_site_data_cremotemcp",
Description: "Clear all site data including cookies, storage, cache, etc. for a tab",
InputSchema: mcp.ToolInputSchema{
Type: "object",
Properties: map[string]any{
"tab": map[string]any{
"type": "string",
"description": "Tab ID (optional, uses current tab)",
},
"timeout": map[string]any{
"type": "integer",
"description": "Timeout in seconds (default: 5)",
"default": 5,
},
},
},
}, func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
// Convert arguments to map
params, ok := request.Params.Arguments.(map[string]any)
if !ok {
return nil, fmt.Errorf("invalid arguments format")
}
tab := getStringParam(params, "tab", "")
timeout := getIntParam(params, "timeout", 5)
err := cremoteServer.client.ClearAllSiteData(tab, timeout)
if err != nil {
return &mcp.CallToolResult{
Content: []mcp.Content{
mcp.NewTextContent(fmt.Sprintf("Error clearing all site data: %v", err)),
},
IsError: true,
}, nil
}
return &mcp.CallToolResult{
Content: []mcp.Content{
mcp.NewTextContent("All site data cleared successfully"),
},
IsError: false,
}, nil
})
mcpServer.AddTool(mcp.Tool{
Name: "web_clear_cookies_cremotemcp",
Description: "Clear cookies for a tab",
InputSchema: mcp.ToolInputSchema{
Type: "object",
Properties: map[string]any{
"tab": map[string]any{
"type": "string",
"description": "Tab ID (optional, uses current tab)",
},
"timeout": map[string]any{
"type": "integer",
"description": "Timeout in seconds (default: 5)",
"default": 5,
},
},
},
}, func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
// Convert arguments to map
params, ok := request.Params.Arguments.(map[string]any)
if !ok {
return nil, fmt.Errorf("invalid arguments format")
}
tab := getStringParam(params, "tab", "")
timeout := getIntParam(params, "timeout", 5)
err := cremoteServer.client.ClearCookies(tab, timeout)
if err != nil {
return &mcp.CallToolResult{
Content: []mcp.Content{
mcp.NewTextContent(fmt.Sprintf("Error clearing cookies: %v", err)),
},
IsError: true,
}, nil
}
return &mcp.CallToolResult{
Content: []mcp.Content{
mcp.NewTextContent("Cookies cleared successfully"),
},
IsError: false,
}, nil
})
mcpServer.AddTool(mcp.Tool{
Name: "web_clear_storage_cremotemcp",
Description: "Clear web storage (localStorage, sessionStorage, IndexedDB, etc.) for a tab",
InputSchema: mcp.ToolInputSchema{
Type: "object",
Properties: map[string]any{
"tab": map[string]any{
"type": "string",
"description": "Tab ID (optional, uses current tab)",
},
"timeout": map[string]any{
"type": "integer",
"description": "Timeout in seconds (default: 5)",
"default": 5,
},
},
},
}, func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
// Convert arguments to map
params, ok := request.Params.Arguments.(map[string]any)
if !ok {
return nil, fmt.Errorf("invalid arguments format")
}
tab := getStringParam(params, "tab", "")
timeout := getIntParam(params, "timeout", 5)
err := cremoteServer.client.ClearStorage(tab, timeout)
if err != nil {
return &mcp.CallToolResult{
Content: []mcp.Content{
mcp.NewTextContent(fmt.Sprintf("Error clearing storage: %v", err)),
},
IsError: true,
}, nil
}
return &mcp.CallToolResult{
Content: []mcp.Content{
mcp.NewTextContent("Storage cleared successfully"),
},
IsError: false,
}, nil
})
// Start the server
log.Printf("Cremote MCP server ready")
if err := server.ServeStdio(mcpServer); err != nil {

199
mcp_cache_test_example.md Normal file
View File

@@ -0,0 +1,199 @@
# MCP Cache and Site Data Management Test Examples
This document provides examples of how to use the new cache and site data management tools through the MCP interface.
## Prerequisites
1. Ensure cremotedaemon is running
2. Ensure Chrome/Chromium is running with remote debugging enabled
3. Configure your MCP client to use the cremote MCP server
## Example 1: Basic Cache Disable/Enable Workflow
```yaml
# Navigate to a test page
web_navigate_cremotemcp:
url: "https://httpbin.org/cache/60"
screenshot: true
# Disable cache for testing
web_disable_cache_cremotemcp:
timeout: 10
# Reload page to test without cache
web_navigate_cremotemcp:
url: "https://httpbin.org/cache/60"
# Re-enable cache
web_enable_cache_cremotemcp:
timeout: 10
```
## Example 2: Performance Testing Workflow
```yaml
# Clear cache before performance test
web_clear_cache_cremotemcp:
timeout: 15
# Disable cache for cold load test
web_disable_cache_cremotemcp:
timeout: 10
# Navigate and measure performance
web_navigate_cremotemcp:
url: "https://example.com"
screenshot: true
# Get performance metrics
web_performance_metrics_cremotemcp: {}
# Enable cache for warm load test
web_enable_cache_cremotemcp:
timeout: 10
# Navigate again and compare
web_navigate_cremotemcp:
url: "https://example.com"
# Get performance metrics again
web_performance_metrics_cremotemcp: {}
```
## Example 3: Multi-Tab Cache Management
```yaml
# Open first tab and disable cache
web_manage_tabs_cremotemcp:
action: "open"
web_disable_cache_cremotemcp:
tab: "tab-1"
timeout: 10
# Open second tab and keep cache enabled
web_manage_tabs_cremotemcp:
action: "open"
# Navigate both tabs to same URL
web_navigate_cremotemcp:
url: "https://httpbin.org/cache/60"
tab: "tab-1"
web_navigate_cremotemcp:
url: "https://httpbin.org/cache/60"
tab: "tab-2"
```
## Example 4: Development Workflow
```yaml
# Disable cache for development
web_disable_cache_cremotemcp:
timeout: 10
# Navigate to development site
web_navigate_cremotemcp:
url: "http://localhost:3000"
# Interact with page
web_interact_cremotemcp:
action: "click"
selector: "#refresh-button"
# Take screenshot for documentation
web_screenshot_enhanced_cremotemcp:
output: "/tmp/dev-screenshot.png"
full_page: true
```
## Error Handling
The cache management tools will return appropriate error messages if:
- The daemon is not running
- Chrome/Chromium is not accessible
- The specified tab doesn't exist
- Network operations timeout
Example error response:
```json
{
"error": "failed to disable cache: tab not found: tab-123",
"isError": true
}
```
## Best Practices
1. **Always set appropriate timeouts** for cache operations (5-15 seconds recommended)
2. **Clear cache before performance tests** to ensure consistent baseline measurements
3. **Disable cache during development** to see changes immediately
4. **Re-enable cache after testing** to restore normal browsing behavior
5. **Use specific tab IDs** when working with multiple tabs to avoid confusion
## Example 5: Authentication Testing Workflow
```yaml
# Clear all site data before testing login
web_clear_all_site_data_cremotemcp:
timeout: 15
# Navigate to login page
web_navigate_cremotemcp:
url: "https://example.com/login"
# Fill login form
web_form_fill_bulk_cremotemcp:
fields:
username: "testuser"
password: "testpass"
# Submit and verify login
web_interact_cremotemcp:
action: "click"
selector: "#login-button"
# Clear cookies to test logout behavior
web_clear_cookies_cremotemcp:
timeout: 10
# Refresh page to verify logout
web_navigate_cremotemcp:
url: "https://example.com/dashboard"
```
## Example 6: Storage Testing Workflow
```yaml
# Clear storage before testing
web_clear_storage_cremotemcp:
timeout: 10
# Navigate to application
web_navigate_cremotemcp:
url: "https://example.com/app"
# Interact with app to create storage data
web_interact_cremotemcp:
action: "click"
selector: "#save-data-button"
# Clear storage to test data persistence
web_clear_storage_cremotemcp:
timeout: 10
# Refresh to test if data is gone
web_navigate_cremotemcp:
url: "https://example.com/app"
```
## Integration with Other Tools
Cache and site data management works seamlessly with other cremote MCP tools:
- Use with `web_performance_metrics_cremotemcp` for performance testing
- Combine with `web_navigate_cremotemcp` for controlled page loading
- Use with `web_screenshot_enhanced_cremotemcp` for visual testing
- Integrate with `web_interact_cremotemcp` for user interaction testing
- Use with `web_form_fill_bulk_cremotemcp` for authentication testing
- Combine with `web_extract_cremotemcp` tools for data verification after clearing

129
test_cache_management.sh Executable file
View File

@@ -0,0 +1,129 @@
#!/bin/bash
# Test script for cache management functionality
# This script demonstrates the new cache management features in cremote
echo "🧪 Testing Cremote Cache Management Features"
echo "============================================="
# Check if daemon is running
echo "📡 Checking daemon status..."
if ! ./cremote status > /dev/null 2>&1; then
echo "❌ Daemon is not running. Please start it with: cremotedaemon"
exit 1
fi
echo "✅ Daemon is running"
# Open a new tab
echo "🌐 Opening new tab..."
TAB_ID=$(./cremote open-tab)
if [ $? -ne 0 ]; then
echo "❌ Failed to open tab"
exit 1
fi
echo "✅ Tab opened: $TAB_ID"
# Load a test page
echo "📄 Loading test page..."
./cremote load-url --url="https://httpbin.org/cache/60" --timeout=10
if [ $? -ne 0 ]; then
echo "❌ Failed to load page"
exit 1
fi
echo "✅ Page loaded"
# Test 1: Disable cache
echo ""
echo "🚫 Test 1: Disabling cache..."
./cremote disable-cache --timeout=10
if [ $? -eq 0 ]; then
echo "✅ Cache disabled successfully"
else
echo "❌ Failed to disable cache"
fi
# Test 2: Enable cache
echo ""
echo "✅ Test 2: Enabling cache..."
./cremote enable-cache --timeout=10
if [ $? -eq 0 ]; then
echo "✅ Cache enabled successfully"
else
echo "❌ Failed to enable cache"
fi
# Test 3: Clear cache
echo ""
echo "🧹 Test 3: Clearing cache..."
./cremote clear-cache --timeout=10
if [ $? -eq 0 ]; then
echo "✅ Cache cleared successfully"
else
echo "❌ Failed to clear cache"
fi
# Test 4: Test with specific tab ID
echo ""
echo "🎯 Test 4: Testing with specific tab ID..."
./cremote disable-cache --tab="$TAB_ID" --timeout=10
if [ $? -eq 0 ]; then
echo "✅ Cache disabled for specific tab successfully"
else
echo "❌ Failed to disable cache for specific tab"
fi
# Clean up
echo ""
echo "🧹 Cleaning up..."
./cremote close-tab --tab="$TAB_ID"
echo "✅ Tab closed"
echo ""
# Test 5: Clear all site data
echo ""
echo "🧹 Test 5: Clearing all site data..."
./cremote clear-all-site-data --timeout=15
if [ $? -eq 0 ]; then
echo "✅ All site data cleared successfully"
else
echo "❌ Failed to clear all site data"
fi
# Test 6: Clear cookies only
echo ""
echo "🍪 Test 6: Clearing cookies..."
./cremote clear-cookies --timeout=10
if [ $? -eq 0 ]; then
echo "✅ Cookies cleared successfully"
else
echo "❌ Failed to clear cookies"
fi
# Test 7: Clear storage only
echo ""
echo "💾 Test 7: Clearing storage..."
./cremote clear-storage --timeout=10
if [ $? -eq 0 ]; then
echo "✅ Storage cleared successfully"
else
echo "❌ Failed to clear storage"
fi
echo "🎉 Cache and site data management tests completed!"
echo ""
echo "📋 Summary of new features:"
echo " • disable-cache: Disables browser cache for testing"
echo " • enable-cache: Re-enables browser cache"
echo " • clear-cache: Clears existing cached resources"
echo " • clear-all-site-data: Clears ALL site data (cookies, storage, cache, etc.)"
echo " • clear-cookies: Clears cookies only"
echo " • clear-storage: Clears web storage only (localStorage, sessionStorage, etc.)"
echo ""
echo "💡 Use cases:"
echo " • Testing: Ensure fresh page loads without cache"
echo " • Performance: Test cold load performance"
echo " • Debugging: Resolve cache-related issues"
echo " • Development: See changes immediately"
echo " • Authentication: Clear cookies to test login/logout flows"
echo " • Privacy: Clear all site data for clean state testing"
echo " • Storage: Clear web storage to test application state"