Add commands for dealing with cache and site data, cookies, etc
This commit is contained in:
43
README.md
43
README.md
@@ -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:
|
||||
|
||||
168
client/client.go
168
client/client.go
@@ -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
BIN
daemon/cremotedaemon
Executable file
Binary file not shown.
400
daemon/daemon.go
400
daemon/daemon.go
@@ -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
138
main.go
@@ -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:")
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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**
|
||||
|
||||
272
mcp/main.go
272
mcp/main.go
@@ -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
199
mcp_cache_test_example.md
Normal 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
129
test_cache_management.sh
Executable 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"
|
||||
Reference in New Issue
Block a user