chromux 0.2.0
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 +152 -0
- package/chrome-tabs.mjs +501 -0
- package/chromux.mjs +847 -0
- package/package.json +13 -0
- package/test.sh +141 -0
package/package.json
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "chromux",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "tmux for Chrome tabs — zero-dependency parallel Chrome tab controller via raw CDP",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"chromux": "./chromux.mjs"
|
|
8
|
+
},
|
|
9
|
+
"engines": {
|
|
10
|
+
"node": ">=22"
|
|
11
|
+
},
|
|
12
|
+
"license": "MIT"
|
|
13
|
+
}
|
package/test.sh
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
set -e
|
|
3
|
+
|
|
4
|
+
CT="$(dirname "$0")/chromux.mjs"
|
|
5
|
+
PROFILE="test-$$"
|
|
6
|
+
PASS=0
|
|
7
|
+
FAIL=0
|
|
8
|
+
|
|
9
|
+
check() {
|
|
10
|
+
local desc="$1" expected="$2" actual="$3"
|
|
11
|
+
if echo "$actual" | grep -q "$expected"; then
|
|
12
|
+
echo " ✓ $desc"
|
|
13
|
+
PASS=$((PASS+1))
|
|
14
|
+
else
|
|
15
|
+
echo " ✗ $desc (expected '$expected', got: $actual)"
|
|
16
|
+
FAIL=$((FAIL+1))
|
|
17
|
+
fi
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
cleanup() {
|
|
21
|
+
echo ""
|
|
22
|
+
echo "--- Cleanup ---"
|
|
23
|
+
node "$CT" kill "$PROFILE" 2>/dev/null || true
|
|
24
|
+
chmod -R u+rwX "$HOME/.chromux/profiles/$PROFILE" 2>/dev/null || true
|
|
25
|
+
rm -rf "$HOME/.chromux/profiles/$PROFILE"
|
|
26
|
+
echo " ✓ cleaned up profile $PROFILE"
|
|
27
|
+
}
|
|
28
|
+
trap cleanup EXIT
|
|
29
|
+
|
|
30
|
+
echo "=== chromux test suite ==="
|
|
31
|
+
echo "profile: $PROFILE"
|
|
32
|
+
echo ""
|
|
33
|
+
|
|
34
|
+
# --- Test 1: Launch ---
|
|
35
|
+
echo "--- Test 1: Launch profile ---"
|
|
36
|
+
R1=$(node "$CT" launch "$PROFILE" 2>/dev/null)
|
|
37
|
+
check "profile launched" "port" "$R1"
|
|
38
|
+
check "profile name" "$PROFILE" "$R1"
|
|
39
|
+
|
|
40
|
+
# --- Test 2: PS ---
|
|
41
|
+
echo ""
|
|
42
|
+
echo "--- Test 2: PS ---"
|
|
43
|
+
PS=$(node "$CT" ps 2>/dev/null)
|
|
44
|
+
check "ps shows profile" "$PROFILE" "$PS"
|
|
45
|
+
check "ps shows running" "running" "$PS"
|
|
46
|
+
|
|
47
|
+
# --- Test 3: Open tabs ---
|
|
48
|
+
echo ""
|
|
49
|
+
echo "--- Test 3: Open tabs ---"
|
|
50
|
+
R3A=$(CHROMUX_PROFILE=$PROFILE node "$CT" open tab-a https://httpbin.org/user-agent 2>/dev/null)
|
|
51
|
+
check "tab-a opened" "httpbin.org/user-agent" "$R3A"
|
|
52
|
+
|
|
53
|
+
R3B=$(CHROMUX_PROFILE=$PROFILE node "$CT" open tab-b https://httpbin.org/ip 2>/dev/null)
|
|
54
|
+
check "tab-b opened" "httpbin.org/ip" "$R3B"
|
|
55
|
+
|
|
56
|
+
# --- Test 4: Isolation ---
|
|
57
|
+
echo ""
|
|
58
|
+
echo "--- Test 4: Tab isolation ---"
|
|
59
|
+
URL_A=$(CHROMUX_PROFILE=$PROFILE node "$CT" eval tab-a "location.href" 2>/dev/null)
|
|
60
|
+
URL_B=$(CHROMUX_PROFILE=$PROFILE node "$CT" eval tab-b "location.href" 2>/dev/null)
|
|
61
|
+
check "tab-a URL correct" "user-agent" "$URL_A"
|
|
62
|
+
check "tab-b URL correct" "/ip" "$URL_B"
|
|
63
|
+
|
|
64
|
+
# --- Test 5: Real Chrome ---
|
|
65
|
+
echo ""
|
|
66
|
+
echo "--- Test 5: Real Chrome ---"
|
|
67
|
+
UA=$(CHROMUX_PROFILE=$PROFILE node "$CT" eval tab-a "navigator.userAgent" 2>/dev/null)
|
|
68
|
+
check "Chrome UA present" "Chrome/" "$UA"
|
|
69
|
+
if echo "$UA" | grep -q "HeadlessChrome"; then
|
|
70
|
+
echo " ✗ HeadlessChrome detected"
|
|
71
|
+
FAIL=$((FAIL+1))
|
|
72
|
+
else
|
|
73
|
+
echo " ✓ Not HeadlessChrome"
|
|
74
|
+
PASS=$((PASS+1))
|
|
75
|
+
fi
|
|
76
|
+
|
|
77
|
+
# --- Test 6: Snapshot ---
|
|
78
|
+
echo ""
|
|
79
|
+
echo "--- Test 6: Snapshot ---"
|
|
80
|
+
CHROMUX_PROFILE=$PROFILE node "$CT" open tab-a https://news.ycombinator.com 2>/dev/null > /dev/null
|
|
81
|
+
sleep 2
|
|
82
|
+
SNAP=$(CHROMUX_PROFILE=$PROFILE node "$CT" snapshot tab-a 2>/dev/null)
|
|
83
|
+
check "snapshot has title" "Hacker News" "$SNAP"
|
|
84
|
+
check "snapshot has @ref" "@1" "$SNAP"
|
|
85
|
+
|
|
86
|
+
# --- Test 7: Screenshot ---
|
|
87
|
+
echo ""
|
|
88
|
+
echo "--- Test 7: Screenshot ---"
|
|
89
|
+
CHROMUX_PROFILE=$PROFILE node "$CT" screenshot tab-a /tmp/chromux-test.png 2>/dev/null > /dev/null
|
|
90
|
+
if [ -f /tmp/chromux-test.png ] && [ -s /tmp/chromux-test.png ]; then
|
|
91
|
+
SIZE=$(wc -c < /tmp/chromux-test.png | tr -d ' ')
|
|
92
|
+
echo " ✓ Screenshot saved (${SIZE} bytes)"
|
|
93
|
+
PASS=$((PASS+1))
|
|
94
|
+
else
|
|
95
|
+
echo " ✗ Screenshot missing or empty"
|
|
96
|
+
FAIL=$((FAIL+1))
|
|
97
|
+
fi
|
|
98
|
+
rm -f /tmp/chromux-test.png
|
|
99
|
+
|
|
100
|
+
# --- Test 8: List ---
|
|
101
|
+
echo ""
|
|
102
|
+
echo "--- Test 8: List sessions ---"
|
|
103
|
+
LIST=$(CHROMUX_PROFILE=$PROFILE node "$CT" list 2>/dev/null)
|
|
104
|
+
check "list shows tab-a" "tab-a" "$LIST"
|
|
105
|
+
check "list shows tab-b" "tab-b" "$LIST"
|
|
106
|
+
|
|
107
|
+
# --- Test 9: Close ---
|
|
108
|
+
echo ""
|
|
109
|
+
echo "--- Test 9: Close tabs ---"
|
|
110
|
+
CHROMUX_PROFILE=$PROFILE node "$CT" close tab-a 2>/dev/null > /dev/null
|
|
111
|
+
CHROMUX_PROFILE=$PROFILE node "$CT" close tab-b 2>/dev/null > /dev/null
|
|
112
|
+
LIST2=$(CHROMUX_PROFILE=$PROFILE node "$CT" list 2>/dev/null)
|
|
113
|
+
check "all tabs closed" "{}" "$LIST2"
|
|
114
|
+
|
|
115
|
+
# --- Test 10: Kill profile ---
|
|
116
|
+
echo ""
|
|
117
|
+
echo "--- Test 10: Kill profile ---"
|
|
118
|
+
node "$CT" kill "$PROFILE" 2>/dev/null > /dev/null
|
|
119
|
+
sleep 1
|
|
120
|
+
PS2=$(node "$CT" ps 2>/dev/null)
|
|
121
|
+
if echo "$PS2" | grep -q "$PROFILE"; then
|
|
122
|
+
echo " ✗ Profile still showing in ps"
|
|
123
|
+
FAIL=$((FAIL+1))
|
|
124
|
+
else
|
|
125
|
+
echo " ✓ Profile killed and removed from ps"
|
|
126
|
+
PASS=$((PASS+1))
|
|
127
|
+
fi
|
|
128
|
+
|
|
129
|
+
# Cancel the EXIT trap since kill already cleaned up
|
|
130
|
+
trap - EXIT
|
|
131
|
+
|
|
132
|
+
# --- Summary ---
|
|
133
|
+
echo ""
|
|
134
|
+
echo "==========================="
|
|
135
|
+
echo "Results: $PASS passed, $FAIL failed"
|
|
136
|
+
if [ $FAIL -eq 0 ]; then
|
|
137
|
+
echo "✓ All tests passed!"
|
|
138
|
+
else
|
|
139
|
+
echo "✗ Some tests failed"
|
|
140
|
+
exit 1
|
|
141
|
+
fi
|