cbrowser 7.4.17 → 7.4.19

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/dist/cli.js CHANGED
@@ -200,12 +200,14 @@ PERFORMANCE REGRESSION (v6.4.0)
200
200
  perf-baseline delete <name> Delete a baseline
201
201
 
202
202
  perf-regression <url> <baseline> Compare current performance against baseline
203
+ --sensitivity <level> strict|normal|lenient (default: normal)
203
204
  --threshold-lcp <n> Max LCP increase % (default: 20)
204
205
  --threshold-cls <n> Max CLS increase (default: 0.1)
205
206
  --threshold-fcp <n> Max FCP increase % (default: 20)
206
207
  --output <file> Save JSON report to file
207
208
  Examples:
208
209
  cbrowser perf-regression "https://example.com" homepage
210
+ cbrowser perf-regression "https://example.com" homepage --sensitivity strict
209
211
  cbrowser perf-regression "https://example.com" homepage --threshold-lcp 30
210
212
 
211
213
  NETWORK / HAR
@@ -1766,9 +1768,13 @@ Documentation: https://github.com/alexandriashai/cbrowser/wiki
1766
1768
  console.error("Error: Session name required");
1767
1769
  process.exit(1);
1768
1770
  }
1769
- const loaded = await browser.loadSession(name);
1770
- if (loaded) {
1771
+ const loadResult = await browser.loadSession(name);
1772
+ if (loadResult.success) {
1771
1773
  console.log(`✓ Session loaded: ${name}`);
1774
+ console.log(` Cookies: ${loadResult.cookiesRestored}, localStorage: ${loadResult.localStorageKeysRestored}, sessionStorage: ${loadResult.sessionStorageKeysRestored}`);
1775
+ if (loadResult.warning) {
1776
+ console.log(` ⚠️ ${loadResult.warning}`);
1777
+ }
1772
1778
  }
1773
1779
  else {
1774
1780
  console.error(`✗ Session not found: ${name}`);
@@ -1777,16 +1783,134 @@ Documentation: https://github.com/alexandriashai/cbrowser/wiki
1777
1783
  break;
1778
1784
  }
1779
1785
  case "list": {
1780
- const sessions = browser.listSessions();
1786
+ const sessions = browser.listSessionsDetailed();
1781
1787
  if (sessions.length === 0) {
1782
1788
  console.log("No saved sessions");
1783
1789
  }
1784
1790
  else {
1785
1791
  console.log("\n📋 Saved Sessions:\n");
1786
- for (const session of sessions) {
1787
- console.log(` - ${session}`);
1792
+ // Table header
1793
+ const nameW = Math.max(16, ...sessions.map((s) => s.name.length)) + 2;
1794
+ const domainW = Math.max(16, ...sessions.map((s) => s.domain.length)) + 2;
1795
+ console.log(` ${"Name".padEnd(nameW)}${"Domain".padEnd(domainW)}${"Created".padEnd(22)}${"Cookies".padEnd(10)}${"Size".padEnd(10)}`);
1796
+ console.log(` ${"─".repeat(nameW)}${"─".repeat(domainW)}${"─".repeat(22)}${"─".repeat(10)}${"─".repeat(10)}`);
1797
+ for (const s of sessions) {
1798
+ const created = new Date(s.created).toLocaleString("en-US", {
1799
+ month: "short", day: "2-digit", year: "numeric", hour: "2-digit", minute: "2-digit",
1800
+ });
1801
+ const size = s.sizeBytes < 1024
1802
+ ? `${s.sizeBytes} B`
1803
+ : `${(s.sizeBytes / 1024).toFixed(1)} KB`;
1804
+ console.log(` ${s.name.padEnd(nameW)}${s.domain.padEnd(domainW)}${created.padEnd(22)}${String(s.cookies).padEnd(10)}${size.padEnd(10)}`);
1805
+ }
1806
+ console.log();
1807
+ }
1808
+ break;
1809
+ }
1810
+ case "show": {
1811
+ if (!name) {
1812
+ console.error("Error: Session name required");
1813
+ process.exit(1);
1814
+ }
1815
+ const details = browser.getSessionDetails(name);
1816
+ if (!details) {
1817
+ console.error(`✗ Session not found: ${name}`);
1818
+ process.exit(1);
1819
+ }
1820
+ const fs = await import("fs");
1821
+ const path = await import("path");
1822
+ const sessionPath = path.join(browser["paths"].sessionsDir, `${name}.json`);
1823
+ const fileSize = fs.statSync(sessionPath).size;
1824
+ console.log(`\n📋 Session: ${name}\n`);
1825
+ console.log(` Domain: ${details.domain}`);
1826
+ console.log(` URL: ${details.url}`);
1827
+ console.log(` Created: ${new Date(details.created).toLocaleString()}`);
1828
+ console.log(` Last Used: ${new Date(details.lastUsed).toLocaleString()}`);
1829
+ console.log(` Viewport: ${details.viewport.width}x${details.viewport.height}`);
1830
+ console.log(` File Size: ${(fileSize / 1024).toFixed(1)} KB`);
1831
+ console.log(`\n Cookies (${details.cookies.length}):`);
1832
+ if (details.cookies.length > 0) {
1833
+ const domains = [...new Set(details.cookies.map((c) => c.domain))];
1834
+ for (const d of domains) {
1835
+ const count = details.cookies.filter((c) => c.domain === d).length;
1836
+ console.log(` ${d}: ${count}`);
1837
+ }
1838
+ }
1839
+ console.log(`\n localStorage (${Object.keys(details.localStorage).length} keys):`);
1840
+ for (const key of Object.keys(details.localStorage).slice(0, 10)) {
1841
+ const val = details.localStorage[key];
1842
+ const preview = val.length > 60 ? val.substring(0, 60) + "..." : val;
1843
+ console.log(` ${key}: ${preview}`);
1844
+ }
1845
+ if (Object.keys(details.localStorage).length > 10) {
1846
+ console.log(` ... and ${Object.keys(details.localStorage).length - 10} more`);
1847
+ }
1848
+ console.log(`\n sessionStorage (${Object.keys(details.sessionStorage).length} keys):`);
1849
+ for (const key of Object.keys(details.sessionStorage).slice(0, 10)) {
1850
+ const val = details.sessionStorage[key];
1851
+ const preview = val.length > 60 ? val.substring(0, 60) + "..." : val;
1852
+ console.log(` ${key}: ${preview}`);
1853
+ }
1854
+ if (Object.keys(details.sessionStorage).length > 10) {
1855
+ console.log(` ... and ${Object.keys(details.sessionStorage).length - 10} more`);
1856
+ }
1857
+ if (details.testCredentials) {
1858
+ console.log(`\n Test Credentials: ${details.testCredentials.email} @ ${details.testCredentials.baseUrl}`);
1859
+ }
1860
+ console.log();
1861
+ break;
1862
+ }
1863
+ case "cleanup": {
1864
+ const olderThan = parseInt(options["older-than"] || "30", 10);
1865
+ if (isNaN(olderThan) || olderThan <= 0) {
1866
+ console.error("Error: --older-than must be a positive number of days");
1867
+ process.exit(1);
1868
+ }
1869
+ const result = browser.cleanupSessions(olderThan);
1870
+ if (result.deleted.length === 0) {
1871
+ console.log(`No sessions older than ${olderThan} days`);
1872
+ }
1873
+ else {
1874
+ console.log(`\n🧹 Cleaned up ${result.deleted.length} session(s):\n`);
1875
+ for (const d of result.deleted) {
1876
+ console.log(` ✓ Deleted: ${d}`);
1788
1877
  }
1789
1878
  }
1879
+ console.log(` ${result.kept.length} session(s) kept`);
1880
+ break;
1881
+ }
1882
+ case "export": {
1883
+ if (!name) {
1884
+ console.error("Error: Session name required");
1885
+ process.exit(1);
1886
+ }
1887
+ const output = options.output || `${name}.json`;
1888
+ const exported = browser.exportSession(name, output);
1889
+ if (exported) {
1890
+ console.log(`✓ Session exported: ${name} → ${output}`);
1891
+ }
1892
+ else {
1893
+ console.error(`✗ Session not found: ${name}`);
1894
+ process.exit(1);
1895
+ }
1896
+ break;
1897
+ }
1898
+ case "import": {
1899
+ // args[0] = "import", args[1] = file path
1900
+ const filePath = args[1];
1901
+ if (!filePath) {
1902
+ console.error("Error: File path required");
1903
+ process.exit(1);
1904
+ }
1905
+ const importName = options.name || filePath.replace(/\.json$/, "").split("/").pop();
1906
+ const imported = browser.importSession(filePath, importName);
1907
+ if (imported) {
1908
+ console.log(`✓ Session imported: ${filePath} → ${importName}`);
1909
+ }
1910
+ else {
1911
+ console.error(`✗ Failed to import session from: ${filePath}`);
1912
+ process.exit(1);
1913
+ }
1790
1914
  break;
1791
1915
  }
1792
1916
  case "delete": {
@@ -1804,7 +1928,15 @@ Documentation: https://github.com/alexandriashai/cbrowser/wiki
1804
1928
  break;
1805
1929
  }
1806
1930
  default:
1807
- console.error("Usage: cbrowser session [save|load|list|delete] <name>");
1931
+ console.error("Usage: cbrowser session [save|load|list|show|delete|cleanup|export|import] <name>");
1932
+ console.error("\n save <name> Save current session");
1933
+ console.error(" load <name> Load a saved session");
1934
+ console.error(" list List all sessions with metadata");
1935
+ console.error(" show <name> Show detailed session info");
1936
+ console.error(" delete <name> Delete a session");
1937
+ console.error(" cleanup --older-than <days> Delete old sessions");
1938
+ console.error(" export <name> --output <file> Export session to file");
1939
+ console.error(" import <file> --name <name> Import session from file");
1808
1940
  }
1809
1941
  break;
1810
1942
  }
@@ -3779,20 +3911,30 @@ Documentation: https://github.com/alexandriashai/cbrowser/wiki
3779
3911
  console.error("Usage: cbrowser perf-regression <url> <baseline-name> [options]");
3780
3912
  console.error("");
3781
3913
  console.error("Options:");
3914
+ console.error(" --sensitivity <level> strict|normal|lenient (default: normal)");
3782
3915
  console.error(" --threshold-lcp <n> Max LCP increase % (default: 20)");
3783
3916
  console.error(" --threshold-cls <n> Max CLS increase absolute (default: 0.1)");
3784
3917
  console.error(" --threshold-fcp <n> Max FCP increase % (default: 20)");
3785
3918
  console.error(" --threshold-ttfb <n> Max TTFB increase % (default: 30)");
3786
3919
  console.error(" --output <file> Save JSON report to file");
3787
3920
  console.error("");
3921
+ console.error("Sensitivity profiles (both % AND absolute must be exceeded):");
3922
+ console.error(" strict: FCP 10%/50ms, LCP 10%/100ms, TTFB 15%/30ms, CLS 10%/0.02");
3923
+ console.error(" normal: FCP 20%/100ms, LCP 20%/200ms, TTFB 20%/50ms, CLS 20%/0.05");
3924
+ console.error(" lenient: FCP 30%/200ms, LCP 30%/400ms, TTFB 30%/100ms, CLS 30%/0.1");
3925
+ console.error("");
3788
3926
  console.error("Examples:");
3789
3927
  console.error(" cbrowser perf-regression https://example.com homepage");
3928
+ console.error(" cbrowser perf-regression https://example.com homepage --sensitivity strict");
3929
+ console.error(" cbrowser perf-regression https://example.com homepage --sensitivity lenient");
3790
3930
  console.error(" cbrowser perf-regression https://example.com homepage --threshold-lcp 30");
3791
3931
  process.exit(1);
3792
3932
  }
3933
+ const sensitivity = options.sensitivity || "normal";
3793
3934
  console.log(`\n🔍 Checking for performance regressions...`);
3794
3935
  console.log(` URL: ${url}`);
3795
3936
  console.log(` Baseline: ${baselineName}`);
3937
+ console.log(` Sensitivity: ${sensitivity}`);
3796
3938
  const thresholds = {};
3797
3939
  if (options["threshold-lcp"])
3798
3940
  thresholds.lcp = parseInt(options["threshold-lcp"]);
@@ -3808,6 +3950,7 @@ Documentation: https://github.com/alexandriashai/cbrowser/wiki
3808
3950
  thresholds.tbt = parseInt(options["threshold-tbt"]);
3809
3951
  const regressionOptions = {
3810
3952
  headless,
3953
+ sensitivity: sensitivity,
3811
3954
  thresholds: Object.keys(thresholds).length > 0 ? thresholds : undefined,
3812
3955
  };
3813
3956
  try {