dashcam 1.4.13-beta.1 → 1.4.13-beta.3
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/bin/dashcam.js +4 -2
- package/lib/recorder.js +2 -2
- package/lib/systemInfo.js +21 -0
- package/package.json +1 -1
- package/691cc08dc2fc02f59ae66f08 (1).mp4 +0 -0
- package/LINUX_PERF_FIX.md +0 -184
- package/LOG_TRACKING_GUIDE.md +0 -225
- package/NPM_PUBLISH_FIX.md +0 -104
- package/PERFORMANCE_TRACKING.md +0 -139
- package/SINGLE_FRAME_VIDEO_FIX.md +0 -129
- package/examples/execute-script.js +0 -150
- package/examples/simple-test.js +0 -37
- package/recording.log +0 -814
- package/sea-bundle.mjs +0 -34595
- package/test-page.html +0 -15
- package/test-perf-linux.js +0 -208
- package/test-perf-tracker.js +0 -52
- package/test-performance-tracking.js +0 -108
- package/test-short-recording.js +0 -287
- package/test-top-processes.js +0 -23
- package/test.log +0 -1
- package/test_run.log +0 -48
package/PERFORMANCE_TRACKING.md
DELETED
|
@@ -1,139 +0,0 @@
|
|
|
1
|
-
# Performance Tracking
|
|
2
|
-
|
|
3
|
-
The Dashcam CLI now includes comprehensive performance tracking during recordings. This feature monitors CPU and memory usage throughout the recording session and includes the data in the log files.
|
|
4
|
-
|
|
5
|
-
## What's Tracked
|
|
6
|
-
|
|
7
|
-
### 1. Dashcam Process Metrics
|
|
8
|
-
- **CPU Usage**: Percentage of CPU used by the Dashcam process
|
|
9
|
-
- **Memory Usage**: Memory consumed by the Dashcam process in bytes and MB
|
|
10
|
-
- **Process Info**: PID, parent PID, CPU time, elapsed time
|
|
11
|
-
|
|
12
|
-
### 2. System-Wide Metrics
|
|
13
|
-
- **Total Memory**: System total and free memory
|
|
14
|
-
- **Memory Usage Percentage**: Overall system memory utilization
|
|
15
|
-
- **CPU Count**: Number of CPU cores available
|
|
16
|
-
|
|
17
|
-
### 3. Top Processes
|
|
18
|
-
- **Top 10 by CPU**: The most CPU-intensive processes running on the system
|
|
19
|
-
- **Top 10 by Memory**: The most memory-intensive processes running on the system
|
|
20
|
-
- **Process Details**: For each top process, tracks:
|
|
21
|
-
- Process name
|
|
22
|
-
- PID
|
|
23
|
-
- CPU usage percentage
|
|
24
|
-
- Memory usage in bytes
|
|
25
|
-
- Parent process ID
|
|
26
|
-
- CPU time and elapsed time
|
|
27
|
-
|
|
28
|
-
## Sampling Frequency
|
|
29
|
-
|
|
30
|
-
Performance metrics are sampled every **1 second** (1000ms) during the recording session.
|
|
31
|
-
|
|
32
|
-
## Output Format
|
|
33
|
-
|
|
34
|
-
Performance data is included in the recording result with the following structure:
|
|
35
|
-
|
|
36
|
-
```javascript
|
|
37
|
-
{
|
|
38
|
-
performance: {
|
|
39
|
-
samples: [
|
|
40
|
-
{
|
|
41
|
-
timestamp: 1700000000000,
|
|
42
|
-
elapsedMs: 1000,
|
|
43
|
-
system: {
|
|
44
|
-
totalMemory: 17179869184,
|
|
45
|
-
freeMemory: 8589934592,
|
|
46
|
-
usedMemory: 8589934592,
|
|
47
|
-
memoryUsagePercent: 50.0,
|
|
48
|
-
cpuCount: 8
|
|
49
|
-
},
|
|
50
|
-
process: {
|
|
51
|
-
cpu: 15.5,
|
|
52
|
-
memory: 134217728,
|
|
53
|
-
pid: 12345,
|
|
54
|
-
ppid: 1,
|
|
55
|
-
ctime: 5000,
|
|
56
|
-
elapsed: 10000
|
|
57
|
-
},
|
|
58
|
-
topProcesses: [
|
|
59
|
-
{
|
|
60
|
-
pid: 54321,
|
|
61
|
-
name: "ffmpeg",
|
|
62
|
-
cpu: 85.2,
|
|
63
|
-
memory: 268435456,
|
|
64
|
-
ppid: 12345,
|
|
65
|
-
ctime: 8500,
|
|
66
|
-
elapsed: 10000
|
|
67
|
-
},
|
|
68
|
-
// ... up to 10 processes
|
|
69
|
-
],
|
|
70
|
-
totalProcesses: 342
|
|
71
|
-
}
|
|
72
|
-
// ... one sample per second
|
|
73
|
-
],
|
|
74
|
-
summary: {
|
|
75
|
-
durationMs: 10000,
|
|
76
|
-
sampleCount: 10,
|
|
77
|
-
monitorInterval: 1000,
|
|
78
|
-
avgProcessCPU: 12.3,
|
|
79
|
-
maxProcessCPU: 18.7,
|
|
80
|
-
avgProcessMemoryBytes: 134217728,
|
|
81
|
-
avgProcessMemoryMB: 128.0,
|
|
82
|
-
maxProcessMemoryBytes: 201326592,
|
|
83
|
-
maxProcessMemoryMB: 192.0,
|
|
84
|
-
avgSystemMemoryUsagePercent: 52.5,
|
|
85
|
-
maxSystemMemoryUsagePercent: 55.3,
|
|
86
|
-
totalSystemMemoryBytes: 17179869184,
|
|
87
|
-
totalSystemMemoryGB: 16.0
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
```
|
|
92
|
-
|
|
93
|
-
## Summary Statistics
|
|
94
|
-
|
|
95
|
-
The performance tracker calculates summary statistics including:
|
|
96
|
-
- **Average and Max Process CPU**: How much CPU the Dashcam process used
|
|
97
|
-
- **Average and Max Process Memory**: Memory consumed by the Dashcam process
|
|
98
|
-
- **Average and Max System Memory Usage**: Overall system memory pressure
|
|
99
|
-
- **Total Duration**: How long the tracking ran
|
|
100
|
-
- **Sample Count**: Number of samples collected
|
|
101
|
-
|
|
102
|
-
## Logging
|
|
103
|
-
|
|
104
|
-
Performance data is logged to the standard Dashcam log files:
|
|
105
|
-
- `~/.dashcam/logs/combined.log` - All log levels including performance samples
|
|
106
|
-
- `~/.dashcam/logs/debug.log` - Debug-level information
|
|
107
|
-
- Console output when running with `--verbose` flag
|
|
108
|
-
|
|
109
|
-
## Testing
|
|
110
|
-
|
|
111
|
-
Run the performance tracking test:
|
|
112
|
-
|
|
113
|
-
```bash
|
|
114
|
-
node test-performance-tracking.js
|
|
115
|
-
```
|
|
116
|
-
|
|
117
|
-
This will:
|
|
118
|
-
1. Start a 10-second recording
|
|
119
|
-
2. Collect performance samples every second
|
|
120
|
-
3. Display detailed performance statistics
|
|
121
|
-
4. Show the top 10 processes at the end of the recording
|
|
122
|
-
|
|
123
|
-
## Use Cases
|
|
124
|
-
|
|
125
|
-
Performance tracking helps with:
|
|
126
|
-
- **Debugging Performance Issues**: Identify when recordings are resource-intensive
|
|
127
|
-
- **Optimization**: Track the impact of code changes on resource usage
|
|
128
|
-
- **System Monitoring**: Understand what other processes are running during recordings
|
|
129
|
-
- **Troubleshooting**: Correlate performance issues with specific applications or system states
|
|
130
|
-
- **Capacity Planning**: Understand resource requirements for different recording scenarios
|
|
131
|
-
|
|
132
|
-
## Implementation Details
|
|
133
|
-
|
|
134
|
-
The performance tracker uses:
|
|
135
|
-
- `pidusage` - For detailed per-process CPU and memory statistics
|
|
136
|
-
- `ps-list` - For listing all system processes
|
|
137
|
-
- `os` module - For system-wide memory and CPU information
|
|
138
|
-
|
|
139
|
-
The tracker runs in parallel with the recording and has minimal overhead (~1% CPU on average).
|
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
# Single-Frame Video & Frame Drop Issues - Root Cause & Fix
|
|
2
|
-
|
|
3
|
-
## Problem Description
|
|
4
|
-
|
|
5
|
-
Videos produced by dashcam-cli had two related issues:
|
|
6
|
-
1. **Single-frame appearance**: Videos appearing as single-frame, even though they contained multiple frames
|
|
7
|
-
2. **Frame drops**: Videos showing significantly shorter duration than actual recording time (e.g., 12 seconds shown vs 68 seconds actual)
|
|
8
|
-
|
|
9
|
-
## Root Causes
|
|
10
|
-
|
|
11
|
-
### Issue 1: Incomplete WebM Container Metadata
|
|
12
|
-
When ffmpeg's VP9 encoder is terminated before it can properly finalize the stream:
|
|
13
|
-
|
|
14
|
-
1. **Missing duration metadata** - The WebM container doesn't have duration information
|
|
15
|
-
2. **Premature file ending** - FFprobe reports "File ended prematurely"
|
|
16
|
-
3. **Playback issues** - Some players show only the first frame because they can't seek without duration metadata
|
|
17
|
-
|
|
18
|
-
### Issue 2: Frame Dropping During Capture
|
|
19
|
-
Frames were being dropped during the recording process due to:
|
|
20
|
-
|
|
21
|
-
1. **Conflicting frame rate settings** - Platform config had hardcoded `-r 30` while fps parameter was set to 10
|
|
22
|
-
2. **Insufficient buffer sizes** - Default thread queue size caused frame drops when encoder couldn't keep up
|
|
23
|
-
3. **Premature stream termination** - The `-shortest` flag caused encoding to stop before all buffered frames were processed
|
|
24
|
-
4. **Missing vsync enforcement** - Frames could be skipped instead of encoded
|
|
25
|
-
|
|
26
|
-
### Example from Real Recording
|
|
27
|
-
|
|
28
|
-
```bash
|
|
29
|
-
# File: 691cb2b4c2fc02f59ae66e21.mp4
|
|
30
|
-
Frame count: 512 frames
|
|
31
|
-
Actual duration: 17.06 seconds (when decoded)
|
|
32
|
-
Container duration: N/A (missing metadata)
|
|
33
|
-
Warning: "File ended prematurely"
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
The video has 512 frames spanning 17 seconds, but players that rely on container metadata see it as a single frame.
|
|
37
|
-
|
|
38
|
-
## Platform Specificity
|
|
39
|
-
|
|
40
|
-
This issue can occur on all platforms but may be more prevalent on Linux due to:
|
|
41
|
-
- Different screen capture performance characteristics
|
|
42
|
-
- Variations in how X11grab delivers frames vs AVFoundation (macOS) or gdigrab (Windows)
|
|
43
|
-
- System load affecting encoder buffer flush timing
|
|
44
|
-
|
|
45
|
-
## Fix Applied
|
|
46
|
-
|
|
47
|
-
### 1. Minimum Recording Duration (recorder.js)
|
|
48
|
-
```javascript
|
|
49
|
-
const MIN_RECORDING_DURATION = 2000; // 2 seconds minimum
|
|
50
|
-
if (recordingDuration < MIN_RECORDING_DURATION) {
|
|
51
|
-
const waitTime = MIN_RECORDING_DURATION - recordingDuration;
|
|
52
|
-
await new Promise(resolve => setTimeout(resolve, waitTime));
|
|
53
|
-
}
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
### 2. Improved FFmpeg Encoding Parameters
|
|
57
|
-
|
|
58
|
-
**Removed conflicting settings:**
|
|
59
|
-
```javascript
|
|
60
|
-
// REMOVED from platform config:
|
|
61
|
-
'-r', '30' // This conflicted with fps parameter
|
|
62
|
-
|
|
63
|
-
// REMOVED from output args:
|
|
64
|
-
'-shortest' // This caused premature termination
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
**Added buffer and sync enforcement:**
|
|
68
|
-
```javascript
|
|
69
|
-
// Input buffering (before -i):
|
|
70
|
-
'-thread_queue_size', '512', // Large input buffer prevents drops
|
|
71
|
-
'-probesize', '50M', // Better stream detection
|
|
72
|
-
|
|
73
|
-
// Output sync enforcement:
|
|
74
|
-
'-vsync', '1', // Constant frame rate - encode every frame
|
|
75
|
-
'-max_muxing_queue_size', '9999' // Large muxing queue prevents drops
|
|
76
|
-
|
|
77
|
-
// Existing improvements:
|
|
78
|
-
'-quality', 'good', // Changed from 'realtime' for better finalization
|
|
79
|
-
'-cpu-used', '4', // Balanced encoding speed
|
|
80
|
-
'-deadline', 'good', // Good quality mode
|
|
81
|
-
'-g', fps.toString(), // Keyframe every second (was 2 seconds)
|
|
82
|
-
'-force_key_frames', `expr:gte(t,n_forced*1)`, // Force keyframes every 1s
|
|
83
|
-
'-fflags', '+genpts', // Generate presentation timestamps
|
|
84
|
-
'-avoid_negative_ts', 'make_zero' // Prevent timestamp issues
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
### 3. Extended Graceful Shutdown Timing
|
|
88
|
-
```javascript
|
|
89
|
-
// Graceful quit: 5s -> 8s (VP9 needs time to finalize)
|
|
90
|
-
// SIGTERM timeout: 10s -> 15s
|
|
91
|
-
// Post-exit wait: 3s (for filesystem sync)
|
|
92
|
-
|
|
93
|
-
currentRecording.stdin.write('q');
|
|
94
|
-
currentRecording.stdin.end(); // Properly close stdin
|
|
95
|
-
```
|
|
96
|
-
|
|
97
|
-
## Testing
|
|
98
|
-
|
|
99
|
-
Use the provided test script to verify recordings:
|
|
100
|
-
|
|
101
|
-
```bash
|
|
102
|
-
# Analyze existing video
|
|
103
|
-
node test-short-recording.js analyze <video-file>
|
|
104
|
-
|
|
105
|
-
# Run automated tests with various durations
|
|
106
|
-
node test-short-recording.js
|
|
107
|
-
```
|
|
108
|
-
|
|
109
|
-
The test checks for:
|
|
110
|
-
- ✅ Frame count > 1
|
|
111
|
-
- ✅ No "File ended prematurely" warnings
|
|
112
|
-
- ✅ Container metadata is complete (duration present)
|
|
113
|
-
- ✅ All platforms (macOS/Linux/Windows)
|
|
114
|
-
|
|
115
|
-
## Prevention
|
|
116
|
-
|
|
117
|
-
The fix ensures proper container finalization by:
|
|
118
|
-
1. Enforcing minimum recording time for multiple frames
|
|
119
|
-
2. Using encoding parameters that prioritize stream finalization
|
|
120
|
-
3. Allowing sufficient time for VP9 encoder to flush buffers
|
|
121
|
-
4. Properly closing stdin before waiting for process exit
|
|
122
|
-
5. Adding safety timeouts before force-killing the encoder
|
|
123
|
-
|
|
124
|
-
## Impact
|
|
125
|
-
|
|
126
|
-
- Short recordings (< 2s) now wait to ensure at least 2 seconds of footage
|
|
127
|
-
- All recordings get properly finalized WebM container metadata
|
|
128
|
-
- Videos play correctly in all players, including web browsers
|
|
129
|
-
- No more "single frame" issues on any platform
|
|
@@ -1,150 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Example: Execute JavaScript on a webpage through the Chrome extension
|
|
5
|
-
*
|
|
6
|
-
* This demonstrates how to:
|
|
7
|
-
* 1. Connect to the Chrome extension via WebSocket
|
|
8
|
-
* 2. Send JavaScript code to execute on the active tab
|
|
9
|
-
* 3. Receive the execution results back
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
import { server } from '../lib/websocket/server.js';
|
|
13
|
-
import { WebTrackerManager } from '../lib/extension-logs/manager.js';
|
|
14
|
-
import { logger } from '../lib/logger.js';
|
|
15
|
-
|
|
16
|
-
async function main() {
|
|
17
|
-
console.log('================================================================');
|
|
18
|
-
console.log(' Chrome Extension Script Execution Example');
|
|
19
|
-
console.log('================================================================\n');
|
|
20
|
-
console.log('Prerequisites:');
|
|
21
|
-
console.log(' 1. Chrome extension must be installed and loaded');
|
|
22
|
-
console.log(' 2. Have a regular webpage open (NOT chrome:// or chrome-extension://)');
|
|
23
|
-
console.log(' 3. For best results, navigate to a simple page like example.com\n');
|
|
24
|
-
|
|
25
|
-
console.log('Starting WebSocket server...');
|
|
26
|
-
|
|
27
|
-
// Start the WebSocket server
|
|
28
|
-
await server.start();
|
|
29
|
-
console.log('WebSocket server started on port:', server.port); // Create the WebTrackerManager
|
|
30
|
-
const manager = new WebTrackerManager(server);
|
|
31
|
-
|
|
32
|
-
// Wait for the Chrome extension to connect
|
|
33
|
-
console.log('\nWaiting for Chrome extension to connect...');
|
|
34
|
-
const connected = await new Promise((resolve) => {
|
|
35
|
-
const timeout = setTimeout(() => {
|
|
36
|
-
console.log('Timeout waiting for connection');
|
|
37
|
-
resolve(false);
|
|
38
|
-
}, 10000);
|
|
39
|
-
|
|
40
|
-
const cleanup = server.on('connection', (client) => {
|
|
41
|
-
console.log('Chrome extension connected!');
|
|
42
|
-
clearTimeout(timeout);
|
|
43
|
-
cleanup();
|
|
44
|
-
resolve(true);
|
|
45
|
-
});
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
if (!connected) {
|
|
49
|
-
console.error('\nChrome extension did not connect.');
|
|
50
|
-
console.error(' Make sure the extension is installed and running.');
|
|
51
|
-
console.error(' Check chrome://extensions to verify it\'s loaded.');
|
|
52
|
-
process.exit(1);
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
// Give it a moment to fully initialize
|
|
56
|
-
await new Promise(resolve => setTimeout(resolve, 500));
|
|
57
|
-
|
|
58
|
-
console.log('\n--- Example 1: Get page title ---');
|
|
59
|
-
try {
|
|
60
|
-
const result = await manager.executeScript({
|
|
61
|
-
code: 'return document.title;'
|
|
62
|
-
});
|
|
63
|
-
console.log('Page title:', result);
|
|
64
|
-
} catch (error) {
|
|
65
|
-
console.error('Error:', error.message);
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
console.log('\n--- Example 2: Get current URL ---');
|
|
69
|
-
try {
|
|
70
|
-
const result = await manager.executeScript({
|
|
71
|
-
code: 'return window.location.href;'
|
|
72
|
-
});
|
|
73
|
-
console.log('Current URL:', result);
|
|
74
|
-
} catch (error) {
|
|
75
|
-
console.error('Error:', error.message);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
console.log('\n--- Example 3: Change page background color ---');
|
|
79
|
-
try {
|
|
80
|
-
const result = await manager.executeScript({
|
|
81
|
-
code: `
|
|
82
|
-
document.body.style.backgroundColor = '#ffcccc';
|
|
83
|
-
return 'Background color changed!';
|
|
84
|
-
`
|
|
85
|
-
});
|
|
86
|
-
console.log('Result:', result);
|
|
87
|
-
} catch (error) {
|
|
88
|
-
console.error('Error:', error.message);
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
console.log('\n--- Example 4: Insert a message on the page ---');
|
|
92
|
-
try {
|
|
93
|
-
const result = await manager.executeScript({
|
|
94
|
-
code: `
|
|
95
|
-
const div = document.createElement('div');
|
|
96
|
-
div.style.cssText = 'position: fixed; top: 20px; right: 20px; background: #4CAF50; color: white; padding: 20px; border-radius: 8px; font-family: Arial; z-index: 10000; box-shadow: 0 4px 6px rgba(0,0,0,0.1);';
|
|
97
|
-
div.textContent = 'Hello from CLI!';
|
|
98
|
-
document.body.appendChild(div);
|
|
99
|
-
|
|
100
|
-
// Remove after 5 seconds
|
|
101
|
-
setTimeout(() => div.remove(), 5000);
|
|
102
|
-
|
|
103
|
-
return 'Message inserted successfully!';
|
|
104
|
-
`
|
|
105
|
-
});
|
|
106
|
-
console.log('Result:', result);
|
|
107
|
-
} catch (error) {
|
|
108
|
-
console.error('Error:', error.message);
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
console.log('\n--- Example 5: Get all links on the page ---');
|
|
112
|
-
try {
|
|
113
|
-
const result = await manager.executeScript({
|
|
114
|
-
code: `
|
|
115
|
-
const links = Array.from(document.querySelectorAll('a'))
|
|
116
|
-
.map(a => ({ text: a.textContent.trim().substring(0, 50), href: a.href }))
|
|
117
|
-
.slice(0, 5);
|
|
118
|
-
return links;
|
|
119
|
-
`
|
|
120
|
-
});
|
|
121
|
-
console.log('First 5 links:', JSON.stringify(result, null, 2));
|
|
122
|
-
} catch (error) {
|
|
123
|
-
console.error('Error:', error.message);
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
console.log('\n--- Example 6: Execute with error handling ---');
|
|
127
|
-
try {
|
|
128
|
-
const result = await manager.executeScript({
|
|
129
|
-
code: `
|
|
130
|
-
// This will cause an error
|
|
131
|
-
nonExistentVariable.doSomething();
|
|
132
|
-
return 'This will not be returned';
|
|
133
|
-
`
|
|
134
|
-
});
|
|
135
|
-
console.log('Result:', result);
|
|
136
|
-
} catch (error) {
|
|
137
|
-
console.error('Expected error caught:', error.message);
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
console.log('\n--- All examples completed! ---');
|
|
141
|
-
|
|
142
|
-
// Clean up
|
|
143
|
-
await server.stop();
|
|
144
|
-
process.exit(0);
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
main().catch(error => {
|
|
148
|
-
console.error('Fatal error:', error);
|
|
149
|
-
process.exit(1);
|
|
150
|
-
});
|
package/examples/simple-test.js
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
import { server } from '../lib/websocket/server.js';
|
|
4
|
-
import { WebTrackerManager } from '../lib/extension-logs/manager.js';
|
|
5
|
-
|
|
6
|
-
async function main() {
|
|
7
|
-
console.log('Simple test - make sure you have example.com or any webpage open\n');
|
|
8
|
-
|
|
9
|
-
await server.start();
|
|
10
|
-
console.log('Server started on port:', server.port);
|
|
11
|
-
|
|
12
|
-
const manager = new WebTrackerManager(server);
|
|
13
|
-
|
|
14
|
-
console.log('Waiting for extension...');
|
|
15
|
-
await new Promise((resolve) => {
|
|
16
|
-
const cleanup = server.on('connection', () => {
|
|
17
|
-
console.log('Connected!\n');
|
|
18
|
-
cleanup();
|
|
19
|
-
resolve();
|
|
20
|
-
});
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
await new Promise(resolve => setTimeout(resolve, 500));
|
|
24
|
-
|
|
25
|
-
console.log('Test: Get page DOM');
|
|
26
|
-
const result = await manager.getPageDOM();
|
|
27
|
-
console.log('Title:', result.title);
|
|
28
|
-
console.log('URL:', result.url);
|
|
29
|
-
console.log('HTML length:', result.html.length, 'characters\n');
|
|
30
|
-
|
|
31
|
-
console.log(result.html)
|
|
32
|
-
|
|
33
|
-
await server.stop();
|
|
34
|
-
process.exit(0);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
main().catch(console.error);
|