browser-cdp 0.6.3 → 0.6.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -45,6 +45,15 @@ browser-cdp cookies export [--path=FILE]
45
45
  browser-cdp cookies import <file>
46
46
  browser-cdp cookies clear
47
47
 
48
+ # Manage localStorage/sessionStorage
49
+ browser-cdp storage get <key>
50
+ browser-cdp storage set <key> <value>
51
+ browser-cdp storage list
52
+ browser-cdp storage clear
53
+ browser-cdp storage export [--path=FILE]
54
+ browser-cdp storage import <file>
55
+ # Add --session for sessionStorage instead of localStorage
56
+
48
57
  # Show page performance metrics
49
58
  browser-cdp insights [--json]
50
59
 
@@ -123,6 +132,20 @@ browser-cdp cookies import session.json
123
132
  # Clear all cookies
124
133
  browser-cdp cookies clear
125
134
 
135
+ # Get/set localStorage values
136
+ browser-cdp storage get authToken
137
+ browser-cdp storage set theme dark
138
+
139
+ # List all storage keys
140
+ browser-cdp storage list
141
+
142
+ # Export/import storage
143
+ browser-cdp storage export
144
+ browser-cdp storage import storage.json
145
+
146
+ # Work with sessionStorage
147
+ browser-cdp storage get tempData --session
148
+
126
149
  # Get page performance insights
127
150
  browser-cdp insights
128
151
  # Returns: TTFB, First Paint, FCP, DOM loaded, resources, memory
@@ -187,6 +210,57 @@ Delete all cookies from the browser:
187
210
  browser-cdp cookies clear
188
211
  ```
189
212
 
213
+ ## Storage Command
214
+
215
+ The `storage` command provides localStorage and sessionStorage management:
216
+
217
+ ### Get/Set Values
218
+
219
+ ```bash
220
+ browser-cdp storage get authToken # Get from localStorage
221
+ browser-cdp storage set theme dark # Set in localStorage
222
+ browser-cdp storage set tempData "session" --session # Set in sessionStorage
223
+ ```
224
+
225
+ ### List Keys
226
+
227
+ ```bash
228
+ browser-cdp storage list # List localStorage keys
229
+ browser-cdp storage list --session # List sessionStorage keys
230
+ ```
231
+
232
+ ### Export/Import
233
+
234
+ Save storage to a JSON file for backup or restore:
235
+
236
+ ```bash
237
+ browser-cdp storage export # Saves to storage.json
238
+ browser-cdp storage export --path app-state.json # Save to specific file
239
+ browser-cdp storage import app-state.json # Restore from file
240
+ ```
241
+
242
+ Output format:
243
+ ```json
244
+ {
245
+ "authToken": "eyJhbGciOiJIUzI1NiIs...",
246
+ "theme": "dark"
247
+ }
248
+ ```
249
+
250
+ ### Clear Storage
251
+
252
+ ```bash
253
+ browser-cdp storage clear # Clear localStorage
254
+ browser-cdp storage clear --session # Clear sessionStorage
255
+ ```
256
+
257
+ ### localStorage vs sessionStorage
258
+
259
+ | Storage Type | Lifetime | Scope | Flag |
260
+ |--------------|----------|-------|------|
261
+ | localStorage | Permanent | Per origin | (default) |
262
+ | sessionStorage | Tab session | Per tab | `--session` |
263
+
190
264
  ## Pre-started Browser
191
265
 
192
266
  If you already have a browser running with CDP enabled, the CLI will connect to it:
package/cli.js CHANGED
@@ -22,6 +22,7 @@ const commands = {
22
22
  console: "./src/console.js",
23
23
  network: "./src/network.js",
24
24
  cookies: "./src/cookies.js",
25
+ storage: "./src/storage.js",
25
26
  insights: "./src/insights.js",
26
27
  lighthouse: "./src/lighthouse.js",
27
28
  };
@@ -43,6 +44,7 @@ function printUsage() {
43
44
  console.log(" console Stream browser console output");
44
45
  console.log(" network Stream network requests/responses");
45
46
  console.log(" cookies Export/import/clear browser cookies");
47
+ console.log(" storage Manage localStorage/sessionStorage");
46
48
  console.log(" insights Show page performance metrics");
47
49
  console.log(" lighthouse Run Lighthouse audit");
48
50
  console.log("");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "browser-cdp",
3
- "version": "0.6.3",
3
+ "version": "0.6.4",
4
4
  "description": "Browser automation via Chrome DevTools Protocol - control Chrome, Brave, Edge with real browser profiles",
5
5
  "type": "module",
6
6
  "bin": {
package/src/storage.js ADDED
@@ -0,0 +1,170 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { readFileSync, writeFileSync } from "node:fs";
4
+ import { chromium } from "playwright";
5
+ import { DEFAULT_PORT, getActivePage } from "./utils.js";
6
+
7
+ const args = process.argv.slice(2);
8
+ const subcommand = args[0];
9
+ const showHelp = args.includes("--help") || args.includes("-h");
10
+ const useSessionStorage = args.includes("--session");
11
+ const storageType = useSessionStorage ? "sessionStorage" : "localStorage";
12
+
13
+ function printUsage() {
14
+ console.log("Usage: storage <subcommand> [options]");
15
+ console.log("");
16
+ console.log("Subcommands:");
17
+ console.log(" get <key> Get value for key");
18
+ console.log(" set <key> <value> Set key to value");
19
+ console.log(" list List all keys");
20
+ console.log(" clear Clear all storage");
21
+ console.log(" export Export storage to JSON file");
22
+ console.log(" import <file> Import storage from JSON file");
23
+ console.log("");
24
+ console.log("Options:");
25
+ console.log(" --session Use sessionStorage instead of localStorage");
26
+ console.log(" --path <file> Output file path for export (default: storage.json)");
27
+ console.log("");
28
+ console.log("Examples:");
29
+ console.log(" storage get token");
30
+ console.log(" storage set theme dark");
31
+ console.log(" storage list");
32
+ console.log(" storage export");
33
+ console.log(" storage export --path session.json --session");
34
+ console.log(" storage import session.json");
35
+ console.log(" storage clear");
36
+ process.exit(0);
37
+ }
38
+
39
+ if (!subcommand || showHelp) {
40
+ printUsage();
41
+ }
42
+
43
+ if (!["get", "set", "list", "clear", "export", "import"].includes(subcommand)) {
44
+ console.error(`Unknown subcommand: ${subcommand}`);
45
+ console.log("Available: get, set, list, clear, export, import");
46
+ process.exit(1);
47
+ }
48
+
49
+ const browser = await chromium.connectOverCDP(`http://localhost:${DEFAULT_PORT}`);
50
+ const contexts = browser.contexts();
51
+ const context = contexts[0];
52
+
53
+ if (!context) {
54
+ console.error("No browser context found");
55
+ process.exit(1);
56
+ }
57
+
58
+ const pages = context.pages();
59
+ const page = getActivePage(pages);
60
+
61
+ if (!page) {
62
+ console.error("No active tab found");
63
+ process.exit(1);
64
+ }
65
+
66
+ const positionalArgs = args.filter((a) => !a.startsWith("--"));
67
+
68
+ if (subcommand === "get") {
69
+ const key = positionalArgs[1];
70
+
71
+ if (!key) {
72
+ console.error("Error: get requires a key");
73
+ process.exit(1);
74
+ }
75
+
76
+ const result = await page.evaluate(
77
+ ([storageType, key]) => window[storageType].getItem(key),
78
+ [storageType, key]
79
+ );
80
+
81
+ if (result === null) {
82
+ console.error(`Key "${key}" not found in ${storageType}`);
83
+ process.exit(1);
84
+ }
85
+
86
+ console.log(result);
87
+ } else if (subcommand === "set") {
88
+ const key = positionalArgs[1];
89
+ const value = positionalArgs.slice(2).join(" ");
90
+
91
+ if (!key || value === "") {
92
+ console.error("Error: set requires <key> <value>");
93
+ process.exit(1);
94
+ }
95
+
96
+ await page.evaluate(
97
+ ([storageType, key, value]) => window[storageType].setItem(key, value),
98
+ [storageType, key, value]
99
+ );
100
+
101
+ console.log(`Set ${key} in ${storageType}`);
102
+ } else if (subcommand === "list") {
103
+ const keys = await page.evaluate(
104
+ (storageType) => Object.keys(window[storageType]),
105
+ storageType
106
+ );
107
+
108
+ if (keys.length === 0) {
109
+ console.log(`No keys found in ${storageType}`);
110
+ } else {
111
+ console.log(`Keys in ${storageType}:`);
112
+ keys.forEach((key) => console.log(` ${key}`));
113
+ }
114
+ } else if (subcommand === "clear") {
115
+ await page.evaluate((storageType) => window[storageType].clear(), storageType);
116
+
117
+ console.log(`Cleared all ${storageType}`);
118
+ } else if (subcommand === "export") {
119
+ const pathIdx = args.findIndex((a) => a === "--path");
120
+ const outputFile = pathIdx !== -1 ? args[pathIdx + 1] : "storage.json";
121
+
122
+ const data = await page.evaluate((storageType) => {
123
+ const storage = window[storageType];
124
+ const result = {};
125
+ for (let i = 0; i < storage.length; i++) {
126
+ const key = storage.key(i);
127
+ result[key] = storage.getItem(key);
128
+ }
129
+ return result;
130
+ }, storageType);
131
+
132
+ writeFileSync(outputFile, JSON.stringify(data, null, 2));
133
+ const count = Object.keys(data).length;
134
+ console.log(`Exported ${count} item(s) from ${storageType} to ${outputFile}`);
135
+ } else if (subcommand === "import") {
136
+ const importFile = positionalArgs[1];
137
+
138
+ if (!importFile) {
139
+ console.error("Error: import requires a file path");
140
+ process.exit(1);
141
+ }
142
+
143
+ let data;
144
+ try {
145
+ data = JSON.parse(readFileSync(importFile, "utf8"));
146
+ } catch (error) {
147
+ console.error(`Error reading file: ${error.message}`);
148
+ process.exit(1);
149
+ }
150
+
151
+ if (typeof data !== "object" || Array.isArray(data)) {
152
+ console.error("Error: Storage file must contain a JSON object");
153
+ process.exit(1);
154
+ }
155
+
156
+ await page.evaluate(
157
+ ([storageType, data]) => {
158
+ const storage = window[storageType];
159
+ for (const [key, value] of Object.entries(data)) {
160
+ storage.setItem(key, value);
161
+ }
162
+ },
163
+ [storageType, data]
164
+ );
165
+
166
+ const count = Object.keys(data).length;
167
+ console.log(`Imported ${count} item(s) to ${storageType} from ${importFile}`);
168
+ }
169
+
170
+ await browser.close();