dashcam 0.8.3 → 1.0.1-beta.2
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/.dashcam/cli-config.json +3 -0
- package/.dashcam/recording.log +135 -0
- package/.dashcam/web-config.json +11 -0
- package/.github/RELEASE.md +59 -0
- package/.github/workflows/build.yml +103 -0
- package/.github/workflows/publish.yml +43 -0
- package/.github/workflows/release.yml +107 -0
- package/LOG_TRACKING_GUIDE.md +225 -0
- package/README.md +709 -155
- package/bin/dashcam.cjs +8 -0
- package/bin/dashcam.js +542 -0
- package/bin/index.js +63 -0
- package/examples/execute-script.js +152 -0
- package/examples/simple-test.js +37 -0
- package/lib/applicationTracker.js +311 -0
- package/lib/auth.js +222 -0
- package/lib/binaries.js +21 -0
- package/lib/config.js +34 -0
- package/lib/extension-logs/helpers.js +182 -0
- package/lib/extension-logs/index.js +347 -0
- package/lib/extension-logs/manager.js +344 -0
- package/lib/ffmpeg.js +156 -0
- package/lib/logTracker.js +23 -0
- package/lib/logger.js +118 -0
- package/lib/logs/index.js +432 -0
- package/lib/permissions.js +85 -0
- package/lib/processManager.js +255 -0
- package/lib/recorder.js +675 -0
- package/lib/store.js +58 -0
- package/lib/tracking/FileTracker.js +98 -0
- package/lib/tracking/FileTrackerManager.js +62 -0
- package/lib/tracking/LogsTracker.js +147 -0
- package/lib/tracking/active-win.js +212 -0
- package/lib/tracking/icons/darwin.js +39 -0
- package/lib/tracking/icons/index.js +167 -0
- package/lib/tracking/icons/windows.js +27 -0
- package/lib/tracking/idle.js +82 -0
- package/lib/tracking.js +23 -0
- package/lib/uploader.js +449 -0
- package/lib/utilities/jsonl.js +77 -0
- package/lib/webLogsDaemon.js +234 -0
- package/lib/websocket/server.js +223 -0
- package/package.json +50 -21
- package/recording.log +814 -0
- package/sea-bundle.mjs +34595 -0
- package/test-page.html +15 -0
- package/test.log +1 -0
- package/test_run.log +48 -0
- package/test_workflow.sh +80 -0
- package/examples/crash-test.js +0 -11
- package/examples/github-issue.sh +0 -1
- package/examples/protocol.html +0 -22
- package/index.js +0 -177
- package/lib.js +0 -199
- package/recorder.js +0 -85
package/README.md
CHANGED
|
@@ -1,260 +1,814 @@
|
|
|
1
|
-
<
|
|
1
|
+
<div align="center">
|
|
2
2
|
|
|
3
|
-
# Dashcam CLI
|
|
3
|
+
# 🎬 Dashcam CLI
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
### Screen Recording for Automated Tests, CI/CD, and AI Agents
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Capture video recordings of automated test runs with synchronized browser logs, application events, and file changes. Built for CI pipelines, custom VMs, and computer-use agents.
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
[](https://www.npmjs.com/package/dashcam)
|
|
10
|
+
[](https://nodejs.org/)
|
|
11
|
+
[](https://opensource.org/licenses/MIT)
|
|
10
12
|
|
|
13
|
+
[Quick Start](#-quick-start) • [CI/CD](#-cicd-integration) • [Examples](#-examples) • [API](#-commands)
|
|
14
|
+
|
|
15
|
+
</div>
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## 🚀 Quick Start
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
# Install in your CI environment
|
|
23
|
+
npm install -g dashcam
|
|
24
|
+
|
|
25
|
+
# Authenticate with your API key (get it from app.testdriver.ai/team)
|
|
26
|
+
dashcam auth $TD_API_KEY
|
|
27
|
+
|
|
28
|
+
# Wrap your test command
|
|
29
|
+
dashcam record --title "E2E Test Run" &
|
|
30
|
+
DASHCAM_PID=$!
|
|
31
|
+
|
|
32
|
+
# Run your tests
|
|
33
|
+
npm run test:e2e
|
|
34
|
+
|
|
35
|
+
# Stop recording and auto-upload
|
|
36
|
+
dashcam stop
|
|
11
37
|
```
|
|
12
|
-
Usage: dashcam [options] [command]
|
|
13
38
|
|
|
14
|
-
|
|
39
|
+
**That's it!** Your test run is recorded, uploaded, and ready to debug. 🎉
|
|
40
|
+
|
|
41
|
+
> 💡 **Get your API key** from [app.testdriver.ai/team](https://app.testdriver.ai/team)
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## ✨ Features
|
|
46
|
+
|
|
47
|
+
### 🎥 **Automated Test Recording**
|
|
48
|
+
- Capture full video of test executions in CI/CD
|
|
49
|
+
- High-quality video powered by FFmpeg
|
|
50
|
+
- Background recording that runs alongside your tests
|
|
51
|
+
- Works with any test framework (Playwright, Selenium, Cypress, Puppeteer, etc.)
|
|
52
|
+
|
|
53
|
+
### 🕵️ **Intelligent Log Tracking**
|
|
54
|
+
Synchronize logs with video timeline for complete observability:
|
|
55
|
+
|
|
56
|
+
- **📂 Application Logs**: Tail any log file in real-time
|
|
57
|
+
```bash
|
|
58
|
+
dashcam logs --add --name=app-logs --type=file --file=/var/log/myapp.log
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
- **🌐 Browser Events**: Capture console logs, network requests, and navigation
|
|
62
|
+
```bash
|
|
63
|
+
dashcam logs --add --name=webapp --type=web --pattern="*localhost:3000*"
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
- **🔄 Perfect Sync**: All events timestamped and aligned with video
|
|
67
|
+
|
|
68
|
+
### ☁️ **CI-Friendly Upload**
|
|
69
|
+
- Automatic cloud storage after test completion
|
|
70
|
+
- Instant shareable links for team debugging
|
|
71
|
+
- Project organization and retention policies
|
|
72
|
+
- No manual intervention required
|
|
73
|
+
|
|
74
|
+
### 🎯 **Perfect for...**
|
|
75
|
+
- 🤖 **CI/CD Pipelines**: Record test runs in GitHub Actions, GitLab CI, Jenkins, etc.
|
|
76
|
+
- 🖥️ **Custom VMs**: Capture agent behavior on headless or virtual machines
|
|
77
|
+
- 🧠 **AI Agents**: Record computer-use agents (Claude, OpenAI, AutoGPT, etc.)
|
|
78
|
+
- � **Test Debugging**: See exactly what happened when tests fail
|
|
79
|
+
- 📊 **QA Validation**: Visual proof of test coverage and behavior
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## � CI/CD Integration
|
|
84
|
+
|
|
85
|
+
### GitHub Actions
|
|
86
|
+
|
|
87
|
+
```yaml
|
|
88
|
+
name: E2E Tests with Video Recording
|
|
89
|
+
|
|
90
|
+
on: [push, pull_request]
|
|
91
|
+
|
|
92
|
+
jobs:
|
|
93
|
+
test:
|
|
94
|
+
runs-on: ubuntu-latest
|
|
95
|
+
steps:
|
|
96
|
+
- uses: actions/checkout@v3
|
|
97
|
+
|
|
98
|
+
- name: Setup Node.js
|
|
99
|
+
uses: actions/setup-node@v3
|
|
100
|
+
with:
|
|
101
|
+
node-version: '18'
|
|
102
|
+
|
|
103
|
+
- name: Install dependencies
|
|
104
|
+
run: npm install
|
|
105
|
+
|
|
106
|
+
- name: Install Dashcam
|
|
107
|
+
run: npm install -g dashcam
|
|
108
|
+
|
|
109
|
+
- name: Authenticate Dashcam
|
|
110
|
+
run: dashcam auth ${{ secrets.TD_API_KEY }}
|
|
111
|
+
|
|
112
|
+
- name: Start recording
|
|
113
|
+
run: |
|
|
114
|
+
dashcam record --title "E2E Tests - ${{ github.sha }}" \
|
|
115
|
+
--description "Automated test run on branch ${{ github.ref_name }}" \
|
|
116
|
+
--project ${{ secrets.DASHCAM_PROJECT_ID }} &
|
|
117
|
+
sleep 2
|
|
118
|
+
|
|
119
|
+
- name: Run tests
|
|
120
|
+
run: npm run test:e2e
|
|
121
|
+
|
|
122
|
+
- name: Stop recording and upload
|
|
123
|
+
if: always()
|
|
124
|
+
run: dashcam stop
|
|
125
|
+
```
|
|
15
126
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
127
|
+
### GitLab CI
|
|
128
|
+
|
|
129
|
+
```yaml
|
|
130
|
+
e2e-tests:
|
|
131
|
+
stage: test
|
|
132
|
+
image: node:18
|
|
133
|
+
before_script:
|
|
134
|
+
- npm install -g dashcam
|
|
135
|
+
- dashcam auth $TD_API_KEY
|
|
136
|
+
script:
|
|
137
|
+
- dashcam record --title "E2E Tests - $CI_COMMIT_SHORT_SHA" &
|
|
138
|
+
- sleep 2
|
|
139
|
+
- npm run test:e2e
|
|
140
|
+
after_script:
|
|
141
|
+
- dashcam stop
|
|
142
|
+
variables:
|
|
143
|
+
TD_API_KEY: $TD_API_KEY
|
|
144
|
+
DASHCAM_PROJECT_ID: $DASHCAM_PROJECT_ID
|
|
145
|
+
```
|
|
19
146
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
147
|
+
### Jenkins
|
|
148
|
+
|
|
149
|
+
```groovy
|
|
150
|
+
pipeline {
|
|
151
|
+
agent any
|
|
152
|
+
|
|
153
|
+
environment {
|
|
154
|
+
TD_API_KEY = credentials('dashcam-api-key')
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
stages {
|
|
158
|
+
stage('Setup') {
|
|
159
|
+
steps {
|
|
160
|
+
sh 'npm install -g dashcam'
|
|
161
|
+
sh 'dashcam auth $TD_API_KEY'
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
stage('Test') {
|
|
166
|
+
steps {
|
|
167
|
+
sh 'dashcam record --title "E2E Tests - ${BUILD_NUMBER}" &'
|
|
168
|
+
sh 'sleep 2'
|
|
169
|
+
sh 'npm run test:e2e'
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
post {
|
|
175
|
+
always {
|
|
176
|
+
sh 'dashcam stop'
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
28
180
|
```
|
|
29
181
|
|
|
30
|
-
|
|
182
|
+
### Docker/Custom VMs
|
|
31
183
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
- [Table of contents](#table-of-contents)
|
|
35
|
-
- [Examples](#examples)
|
|
36
|
-
- [CLI](#cli)
|
|
37
|
-
- [Setup](#setup)
|
|
38
|
-
- [Auth](#auth)
|
|
39
|
-
- [Record CLI](#record-cli)
|
|
40
|
-
- [Pipe command output into dashcam for recording](#pipe-command-output-into-dashcam-for-recording)
|
|
41
|
-
- [Create a Replay](#create-a-replay)
|
|
42
|
-
- [Return a rich markdown link](#return-a-rich-markdown-link)
|
|
43
|
-
- [Set a replay title](#set-a-replay-title)
|
|
44
|
-
- [Set a project to publish to](#set-a-project-to-publish-to)
|
|
45
|
-
- [Attach the last 20 CLI commands to the replay](#attach-the-last-20-cli-commands-to-the-replay)
|
|
46
|
-
- [Attach a logfile to the replay](#attach-a-logfile-to-the-replay)
|
|
47
|
-
- [GitHub CLI](#github-cli)
|
|
48
|
-
- [Create a github issue with a replay in the description](#create-a-github-issue-with-a-replay-in-the-description)
|
|
49
|
-
- [Create a github pull request with a replay in the description](#create-a-github-pull-request-with-a-replay-in-the-description)
|
|
50
|
-
- [Append a 30 second replay to a commit](#append-a-30-second-replay-to-a-commit)
|
|
51
|
-
- [Advanced Usage](#advanced-usage)
|
|
52
|
-
- [Web](#web)
|
|
53
|
-
- [Setup](#setup-1)
|
|
54
|
-
- [HTML Anchor Tag](#html-anchor-tag)
|
|
55
|
-
- [JS Error Handler](#js-error-handler)
|
|
56
|
-
- [NodeJS SDK](#nodejs-sdk)
|
|
57
|
-
- [Setup](#setup-2)
|
|
58
|
-
- [Create a Replay](#create-a-replay-1)
|
|
59
|
-
- [Error Handler](#error-handler)
|
|
60
|
-
- [Ideas](#ideas)
|
|
184
|
+
```dockerfile
|
|
185
|
+
FROM node:18
|
|
61
186
|
|
|
62
|
-
#
|
|
187
|
+
# Install Dashcam
|
|
188
|
+
RUN npm install -g dashcam
|
|
63
189
|
|
|
64
|
-
|
|
190
|
+
# Your app setup
|
|
191
|
+
WORKDIR /app
|
|
192
|
+
COPY . .
|
|
193
|
+
RUN npm install
|
|
65
194
|
|
|
66
|
-
|
|
195
|
+
# Authenticate (use build args or runtime env)
|
|
196
|
+
ARG TD_API_KEY
|
|
197
|
+
RUN dashcam auth $TD_API_KEY
|
|
67
198
|
|
|
68
|
-
|
|
199
|
+
# Run tests with recording
|
|
200
|
+
CMD ["sh", "-c", "dashcam record --title 'Container Tests' & sleep 2 && npm test && dashcam stop"]
|
|
201
|
+
```
|
|
69
202
|
|
|
70
|
-
|
|
71
|
-
|
|
203
|
+
---
|
|
204
|
+
|
|
205
|
+
## 🤖 AI Agent Integration
|
|
206
|
+
|
|
207
|
+
### Recording Computer-Use Agents
|
|
208
|
+
|
|
209
|
+
Perfect for capturing AI agent behavior (Claude Computer Use, OpenAI Agents, AutoGPT, etc.):
|
|
210
|
+
|
|
211
|
+
```javascript
|
|
212
|
+
import { spawn } from 'child_process';
|
|
213
|
+
|
|
214
|
+
async function runAgentWithRecording(agentTask) {
|
|
215
|
+
// Start recording
|
|
216
|
+
const recording = spawn('dashcam', [
|
|
217
|
+
'record',
|
|
218
|
+
'--title', `Agent Task: ${agentTask}`,
|
|
219
|
+
'--description', 'AI agent execution recording'
|
|
220
|
+
]);
|
|
221
|
+
|
|
222
|
+
// Wait for recording to initialize
|
|
223
|
+
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
224
|
+
|
|
225
|
+
try {
|
|
226
|
+
// Run your AI agent
|
|
227
|
+
await runAgent(agentTask);
|
|
228
|
+
} finally {
|
|
229
|
+
// Always stop and upload recording
|
|
230
|
+
spawn('dashcam', ['stop']);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
72
233
|
```
|
|
73
234
|
|
|
74
|
-
###
|
|
235
|
+
### Python Agent Integration
|
|
236
|
+
|
|
237
|
+
```python
|
|
238
|
+
import subprocess
|
|
239
|
+
import time
|
|
240
|
+
|
|
241
|
+
def record_agent_execution(task_description):
|
|
242
|
+
# Start recording
|
|
243
|
+
recording = subprocess.Popen([
|
|
244
|
+
'dashcam', 'record',
|
|
245
|
+
'--title', f'Agent Task: {task_description}',
|
|
246
|
+
'--description', 'AI agent execution'
|
|
247
|
+
])
|
|
248
|
+
|
|
249
|
+
time.sleep(2) # Let recording initialize
|
|
250
|
+
|
|
251
|
+
try:
|
|
252
|
+
# Run your agent code
|
|
253
|
+
run_my_agent()
|
|
254
|
+
finally:
|
|
255
|
+
# Stop and upload
|
|
256
|
+
subprocess.run(['dashcam', 'stop'])
|
|
257
|
+
|
|
258
|
+
# Usage
|
|
259
|
+
record_agent_execution("Browse web and fill form")
|
|
260
|
+
```
|
|
75
261
|
|
|
76
|
-
|
|
262
|
+
---
|
|
77
263
|
|
|
78
|
-
|
|
79
|
-
|
|
264
|
+
## �📦 Installation
|
|
265
|
+
|
|
266
|
+
### NPM (Recommended for CI)
|
|
267
|
+
```bash
|
|
268
|
+
npm install -g dashcam
|
|
80
269
|
```
|
|
81
270
|
|
|
82
|
-
###
|
|
271
|
+
### Project Dependency
|
|
272
|
+
```bash
|
|
273
|
+
npm install --save-dev dashcam
|
|
274
|
+
```
|
|
83
275
|
|
|
84
|
-
|
|
276
|
+
Then in your package.json:
|
|
277
|
+
```json
|
|
278
|
+
{
|
|
279
|
+
"scripts": {
|
|
280
|
+
"test:recorded": "dashcam record --title 'Test Run' & sleep 2 && npm test; dashcam stop"
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
```
|
|
85
284
|
|
|
285
|
+
### From Source
|
|
286
|
+
```bash
|
|
287
|
+
git clone https://github.com/testdriverai/dashcam.git
|
|
288
|
+
cd dashcam
|
|
289
|
+
npm install
|
|
290
|
+
npm link
|
|
86
291
|
```
|
|
87
|
-
|
|
292
|
+
|
|
293
|
+
### Requirements
|
|
294
|
+
- **Node.js** 14.0.0 or higher
|
|
295
|
+
- **FFmpeg** (bundled automatically via ffmpeg-static)
|
|
296
|
+
- **Display server** (X11, Wayland, or macOS windowing system)
|
|
297
|
+
|
|
298
|
+
---
|
|
299
|
+
|
|
300
|
+
## 🎯 Examples
|
|
301
|
+
|
|
302
|
+
### Example 1: Playwright Test Suite
|
|
303
|
+
|
|
304
|
+
```bash
|
|
305
|
+
#!/bin/bash
|
|
306
|
+
set -e
|
|
307
|
+
|
|
308
|
+
# Setup
|
|
309
|
+
dashcam auth $TD_API_KEY
|
|
310
|
+
|
|
311
|
+
# Configure browser log tracking
|
|
312
|
+
dashcam logs --add --name=playwright --type=web --pattern="*localhost:*"
|
|
313
|
+
|
|
314
|
+
# Start recording
|
|
315
|
+
dashcam record --title "Playwright E2E Suite" \
|
|
316
|
+
--description "Full test suite execution" &
|
|
317
|
+
|
|
318
|
+
sleep 2
|
|
319
|
+
|
|
320
|
+
# Run Playwright tests
|
|
321
|
+
npx playwright test
|
|
322
|
+
|
|
323
|
+
# Stop and upload
|
|
324
|
+
dashcam stop
|
|
88
325
|
```
|
|
89
326
|
|
|
90
|
-
|
|
327
|
+
### Example 2: Selenium Grid
|
|
328
|
+
|
|
329
|
+
```bash
|
|
330
|
+
#!/bin/bash
|
|
331
|
+
|
|
332
|
+
# Track application logs
|
|
333
|
+
dashcam logs --add --name=app --type=file --file=/var/log/app.log
|
|
334
|
+
dashcam logs --add --name=selenium --type=file --file=/var/log/selenium.log
|
|
91
335
|
|
|
336
|
+
# Start recording
|
|
337
|
+
dashcam record --title "Selenium Grid Tests" --project my-project &
|
|
338
|
+
|
|
339
|
+
sleep 2
|
|
340
|
+
|
|
341
|
+
# Run tests on Selenium Grid
|
|
342
|
+
pytest tests/selenium/ --hub=http://selenium-hub:4444
|
|
343
|
+
|
|
344
|
+
# Cleanup
|
|
345
|
+
dashcam stop
|
|
92
346
|
```
|
|
93
|
-
|
|
347
|
+
|
|
348
|
+
### Example 3: Custom Test Framework
|
|
349
|
+
|
|
350
|
+
```javascript
|
|
351
|
+
// test-runner.js
|
|
352
|
+
import { exec } from 'child_process';
|
|
353
|
+
import { promisify } from 'util';
|
|
354
|
+
|
|
355
|
+
const execAsync = promisify(exec);
|
|
356
|
+
|
|
357
|
+
async function runTestsWithRecording() {
|
|
358
|
+
// Start recording
|
|
359
|
+
exec('dashcam record --title "Custom Tests" &');
|
|
360
|
+
|
|
361
|
+
// Wait for initialization
|
|
362
|
+
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
363
|
+
|
|
364
|
+
try {
|
|
365
|
+
// Run your custom test framework
|
|
366
|
+
await execAsync('node tests/runner.js');
|
|
367
|
+
console.log('Tests completed successfully');
|
|
368
|
+
} catch (error) {
|
|
369
|
+
console.error('Tests failed:', error);
|
|
370
|
+
throw error;
|
|
371
|
+
} finally {
|
|
372
|
+
// Always upload the recording
|
|
373
|
+
await execAsync('dashcam stop');
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
runTestsWithRecording().catch(console.error);
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
### Example 4: Multi-Service Test Environment
|
|
381
|
+
|
|
382
|
+
```bash
|
|
383
|
+
#!/bin/bash
|
|
384
|
+
|
|
385
|
+
# Setup log tracking for all services
|
|
386
|
+
dashcam logs --add --name=frontend --type=file --file=/var/log/frontend.log
|
|
387
|
+
dashcam logs --add --name=backend --type=file --file=/var/log/backend.log
|
|
388
|
+
dashcam logs --add --name=database --type=file --file=/var/log/postgres.log
|
|
389
|
+
|
|
390
|
+
# Track web apps
|
|
391
|
+
dashcam logs --add --name=app --type=web --pattern="*localhost:3000*"
|
|
392
|
+
dashcam logs --add --name=admin --type=web --pattern="*localhost:8080*"
|
|
393
|
+
|
|
394
|
+
# Start recording
|
|
395
|
+
dashcam record --title "Integration Tests" \
|
|
396
|
+
--description "# Multi-service test\n\nFrontend, backend, and database" &
|
|
397
|
+
|
|
398
|
+
sleep 2
|
|
399
|
+
|
|
400
|
+
# Start services
|
|
401
|
+
docker-compose up -d
|
|
402
|
+
|
|
403
|
+
# Wait for services to be ready
|
|
404
|
+
sleep 10
|
|
405
|
+
|
|
406
|
+
# Run integration tests
|
|
407
|
+
npm run test:integration
|
|
408
|
+
|
|
409
|
+
# Cleanup
|
|
410
|
+
docker-compose down
|
|
411
|
+
dashcam stop
|
|
94
412
|
```
|
|
95
413
|
|
|
96
|
-
|
|
414
|
+
---
|
|
97
415
|
|
|
98
|
-
|
|
416
|
+
## 📚 Commands
|
|
99
417
|
|
|
418
|
+
### `dashcam auth <apiKey>`
|
|
419
|
+
Authenticate with your TestDriver API key.
|
|
420
|
+
|
|
421
|
+
> 💡 **Get your API key** from [app.testdriver.ai/team](https://app.testdriver.ai/team)
|
|
422
|
+
|
|
423
|
+
```bash
|
|
424
|
+
dashcam auth 4e93d8bf-3886-4d26-a144-116c4063522d
|
|
100
425
|
```
|
|
101
|
-
|
|
426
|
+
|
|
427
|
+
**In CI environments:**
|
|
428
|
+
```bash
|
|
429
|
+
# Use environment variable
|
|
430
|
+
dashcam auth $TD_API_KEY
|
|
102
431
|
```
|
|
103
432
|
|
|
104
|
-
|
|
433
|
+
### `dashcam record [options]`
|
|
434
|
+
Start a new background recording for your test run.
|
|
435
|
+
|
|
436
|
+
**Options:**
|
|
437
|
+
- `-t, --title <title>` - Recording title (e.g., "E2E Test Suite")
|
|
438
|
+
- `-d, --description <description>` - Description (supports Markdown)
|
|
439
|
+
- `-p, --project <project>` - Project ID for organization
|
|
440
|
+
- `-f, --fps <fps>` - Frames per second (default: 30)
|
|
441
|
+
- `-a, --audio` - Include audio (experimental)
|
|
442
|
+
- `-o, --output <path>` - Custom output path
|
|
443
|
+
- `-v, --verbose` - Enable verbose logging
|
|
444
|
+
|
|
445
|
+
**Examples:**
|
|
446
|
+
```bash
|
|
447
|
+
# Basic test recording
|
|
448
|
+
dashcam record --title "Nightly E2E Tests" &
|
|
449
|
+
|
|
450
|
+
# With project and metadata
|
|
451
|
+
dashcam record --title "Sprint 23 Tests" \
|
|
452
|
+
--description "Testing new authentication flow" \
|
|
453
|
+
--project proj_abc123 &
|
|
454
|
+
|
|
455
|
+
# High FPS for smooth playback
|
|
456
|
+
dashcam record --fps 60 --title "UI Animation Tests" &
|
|
457
|
+
```
|
|
105
458
|
|
|
106
|
-
|
|
459
|
+
### `dashcam stop`
|
|
460
|
+
Stop the current recording and upload it. Always call this in CI, even if tests fail.
|
|
107
461
|
|
|
462
|
+
```bash
|
|
463
|
+
dashcam stop
|
|
108
464
|
```
|
|
109
|
-
|
|
465
|
+
|
|
466
|
+
**CI Best Practice:**
|
|
467
|
+
```yaml
|
|
468
|
+
# GitHub Actions
|
|
469
|
+
- name: Stop recording and upload
|
|
470
|
+
if: always() # Run even if tests fail
|
|
471
|
+
run: dashcam stop
|
|
110
472
|
```
|
|
111
473
|
|
|
112
|
-
|
|
474
|
+
### `dashcam status`
|
|
475
|
+
Check if a recording is in progress.
|
|
476
|
+
|
|
477
|
+
```bash
|
|
478
|
+
dashcam status
|
|
479
|
+
# Output:
|
|
480
|
+
# Recording in progress
|
|
481
|
+
# Duration: 45.2 seconds
|
|
482
|
+
# PID: 12345
|
|
483
|
+
# Started: 11/6/2025, 2:30:15 PM
|
|
484
|
+
# Title: Bug Investigation
|
|
485
|
+
```
|
|
113
486
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
487
|
+
### `dashcam logs [options]`
|
|
488
|
+
Manage log tracking configurations.
|
|
489
|
+
|
|
490
|
+
**Options:**
|
|
491
|
+
- `--add` - Add a new log tracker
|
|
492
|
+
- `--remove <id>` - Remove a tracker by ID
|
|
493
|
+
- `--list` - List all configured trackers
|
|
494
|
+
- `--status` - Show tracking status with event counts
|
|
495
|
+
- `--name <name>` - Tracker name (required with --add)
|
|
496
|
+
- `--type <type>` - Type: "web" or "file" (required with --add)
|
|
497
|
+
- `--pattern <pattern>` - URL pattern for web trackers (can specify multiple)
|
|
498
|
+
- `--file <file>` - File path for file trackers
|
|
499
|
+
|
|
500
|
+
**Examples:**
|
|
501
|
+
```bash
|
|
502
|
+
# Add web tracker with multiple patterns
|
|
503
|
+
dashcam logs --add --name=social --type=web \
|
|
504
|
+
--pattern="*facebook.com*" \
|
|
505
|
+
--pattern="*twitter.com*"
|
|
506
|
+
|
|
507
|
+
# Add file tracker
|
|
508
|
+
dashcam logs --add --name=app --type=file --file=/var/log/app.log
|
|
509
|
+
|
|
510
|
+
# List all trackers
|
|
511
|
+
dashcam logs --list
|
|
512
|
+
|
|
513
|
+
# Check activity
|
|
514
|
+
dashcam logs --status
|
|
117
515
|
```
|
|
118
516
|
|
|
119
|
-
###
|
|
517
|
+
### `dashcam upload [filePath] [options]`
|
|
518
|
+
Upload a recording file or recover from interruption.
|
|
120
519
|
|
|
121
|
-
|
|
122
|
-
|
|
520
|
+
**Options:**
|
|
521
|
+
- `-t, --title <title>` - Recording title
|
|
522
|
+
- `-d, --description <description>` - Description
|
|
523
|
+
- `-p, --project <project>` - Project ID
|
|
524
|
+
- `--recover` - Recover interrupted recording
|
|
123
525
|
|
|
124
|
-
|
|
526
|
+
**Examples:**
|
|
527
|
+
```bash
|
|
528
|
+
# Upload specific file
|
|
529
|
+
dashcam upload /path/to/recording.webm --title "My Recording"
|
|
125
530
|
|
|
126
|
-
|
|
531
|
+
# Recover from interruption
|
|
532
|
+
dashcam upload --recover
|
|
127
533
|
```
|
|
128
534
|
|
|
129
|
-
###
|
|
535
|
+
### `dashcam logout`
|
|
536
|
+
Clear authentication credentials.
|
|
130
537
|
|
|
131
|
-
```
|
|
132
|
-
|
|
538
|
+
```bash
|
|
539
|
+
dashcam logout
|
|
133
540
|
```
|
|
134
541
|
|
|
135
|
-
|
|
542
|
+
---
|
|
543
|
+
|
|
544
|
+
## 🔧 Advanced Usage
|
|
545
|
+
|
|
546
|
+
### Pattern Matching for Web Trackers
|
|
547
|
+
|
|
548
|
+
Web trackers support powerful wildcard patterns for capturing browser events during automated tests:
|
|
136
549
|
|
|
137
|
-
```
|
|
138
|
-
|
|
550
|
+
```bash
|
|
551
|
+
# Match any subdomain
|
|
552
|
+
dashcam logs --add --name=app --type=web --pattern="*.myapp.com*"
|
|
553
|
+
|
|
554
|
+
# Match specific paths
|
|
555
|
+
dashcam logs --add --name=admin --type=web --pattern="*app.com/admin/*"
|
|
556
|
+
|
|
557
|
+
# Match local dev servers (common in tests)
|
|
558
|
+
dashcam logs --add --name=dev --type=web --pattern="*localhost:*"
|
|
559
|
+
|
|
560
|
+
# Match test environments
|
|
561
|
+
dashcam logs --add --name=staging --type=web \
|
|
562
|
+
--pattern="*staging.myapp.com*" \
|
|
563
|
+
--pattern="*test.myapp.com*"
|
|
139
564
|
```
|
|
140
565
|
|
|
141
|
-
###
|
|
566
|
+
### Working with Log Files in Tests
|
|
567
|
+
|
|
568
|
+
```bash
|
|
569
|
+
# Ensure log files exist before starting
|
|
570
|
+
mkdir -p /var/log/myapp
|
|
571
|
+
touch /var/log/myapp/app.log
|
|
572
|
+
touch /var/log/myapp/error.log
|
|
573
|
+
|
|
574
|
+
# Add to tracking
|
|
575
|
+
dashcam logs --add --name=app --type=file --file=/var/log/myapp/app.log
|
|
576
|
+
dashcam logs --add --name=errors --type=file --file=/var/log/myapp/error.log
|
|
577
|
+
|
|
578
|
+
# Start recording
|
|
579
|
+
dashcam record --title "Test Run with Logs" &
|
|
142
580
|
|
|
143
|
-
|
|
144
|
-
|
|
581
|
+
sleep 2
|
|
582
|
+
|
|
583
|
+
# Your tests run and write logs
|
|
584
|
+
npm test
|
|
585
|
+
|
|
586
|
+
# All logs are synchronized with video
|
|
587
|
+
dashcam stop
|
|
145
588
|
```
|
|
146
589
|
|
|
147
|
-
###
|
|
590
|
+
### Environment Variables
|
|
591
|
+
|
|
592
|
+
For CI/CD environments, use environment variables instead of hardcoding:
|
|
148
593
|
|
|
149
|
-
|
|
594
|
+
```bash
|
|
595
|
+
# Set in CI environment
|
|
596
|
+
export TD_API_KEY="your-api-key"
|
|
597
|
+
export DASHCAM_PROJECT_ID="proj_abc123"
|
|
150
598
|
|
|
151
|
-
|
|
152
|
-
|
|
599
|
+
# Use in scripts
|
|
600
|
+
dashcam auth $TD_API_KEY
|
|
601
|
+
dashcam record --title "Tests" --project $DASHCAM_PROJECT_ID &
|
|
153
602
|
```
|
|
154
603
|
|
|
155
|
-
|
|
604
|
+
### Programmatic Usage in Test Frameworks
|
|
605
|
+
|
|
606
|
+
#### Jest Integration
|
|
607
|
+
|
|
608
|
+
```javascript
|
|
609
|
+
// jest.config.js
|
|
610
|
+
module.exports = {
|
|
611
|
+
globalSetup: './test/setup.js',
|
|
612
|
+
globalTeardown: './test/teardown.js'
|
|
613
|
+
};
|
|
614
|
+
|
|
615
|
+
// test/setup.js
|
|
616
|
+
import { exec } from 'child_process';
|
|
156
617
|
|
|
157
|
-
|
|
618
|
+
export default async function globalSetup() {
|
|
619
|
+
console.log('Starting Dashcam recording...');
|
|
620
|
+
exec('dashcam record --title "Jest Test Suite" &');
|
|
621
|
+
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
622
|
+
}
|
|
158
623
|
|
|
159
|
-
|
|
624
|
+
// test/teardown.js
|
|
625
|
+
import { execSync } from 'child_process';
|
|
160
626
|
|
|
161
|
-
|
|
162
|
-
|
|
627
|
+
export default async function globalTeardown() {
|
|
628
|
+
console.log('Stopping Dashcam recording...');
|
|
629
|
+
execSync('dashcam stop');
|
|
630
|
+
}
|
|
163
631
|
```
|
|
164
632
|
|
|
165
|
-
|
|
633
|
+
#### Mocha Integration
|
|
634
|
+
|
|
635
|
+
```javascript
|
|
636
|
+
// test/hooks.js
|
|
637
|
+
import { exec, execSync } from 'child_process';
|
|
638
|
+
|
|
639
|
+
before(async function() {
|
|
640
|
+
this.timeout(5000);
|
|
641
|
+
console.log('Starting recording...');
|
|
642
|
+
exec('dashcam record --title "Mocha Tests" &');
|
|
643
|
+
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
644
|
+
});
|
|
166
645
|
|
|
646
|
+
after(function() {
|
|
647
|
+
this.timeout(10000);
|
|
648
|
+
console.log('Uploading recording...');
|
|
649
|
+
execSync('dashcam stop');
|
|
650
|
+
});
|
|
167
651
|
```
|
|
168
|
-
|
|
652
|
+
|
|
653
|
+
#### Pytest Integration
|
|
654
|
+
|
|
655
|
+
```python
|
|
656
|
+
# conftest.py
|
|
657
|
+
import subprocess
|
|
658
|
+
import time
|
|
659
|
+
import pytest
|
|
660
|
+
|
|
661
|
+
@pytest.fixture(scope="session", autouse=True)
|
|
662
|
+
def record_session():
|
|
663
|
+
# Start recording
|
|
664
|
+
print("Starting Dashcam recording...")
|
|
665
|
+
subprocess.Popen([
|
|
666
|
+
'dashcam', 'record',
|
|
667
|
+
'--title', 'Pytest Test Suite'
|
|
668
|
+
])
|
|
669
|
+
time.sleep(2)
|
|
670
|
+
|
|
671
|
+
yield
|
|
672
|
+
|
|
673
|
+
# Stop and upload
|
|
674
|
+
print("Stopping recording...")
|
|
675
|
+
subprocess.run(['dashcam', 'stop'])
|
|
169
676
|
```
|
|
170
677
|
|
|
171
|
-
|
|
678
|
+
---
|
|
172
679
|
|
|
173
|
-
|
|
174
|
-
|
|
680
|
+
## 🌐 Browser Extension for Test Automation
|
|
681
|
+
|
|
682
|
+
For web test automation (Playwright, Selenium, Puppeteer, etc.), install the Dashcam browser extension to capture:
|
|
683
|
+
|
|
684
|
+
- **Console logs** from your application
|
|
685
|
+
- **Network requests** and responses
|
|
686
|
+
- **JavaScript errors** and warnings
|
|
687
|
+
- **Page navigation** events
|
|
688
|
+
|
|
689
|
+
### Setup
|
|
690
|
+
|
|
691
|
+
1. **Install extension** (Chrome/Firefox)
|
|
692
|
+
2. **Start Dashcam CLI** - Extension auto-connects via WebSocket
|
|
693
|
+
3. **Run your tests** - All browser events captured automatically
|
|
694
|
+
4. **Upload recording** - Browser logs included alongside video
|
|
695
|
+
|
|
696
|
+
The CLI automatically starts a WebSocket server on available ports (10368, 16240, 21855, 24301, or 25928).
|
|
697
|
+
|
|
698
|
+
### Headless Testing
|
|
699
|
+
|
|
700
|
+
For headless browsers in CI, browser extension features won't be available, but you can still:
|
|
701
|
+
- Record the full test execution video
|
|
702
|
+
- Track application log files
|
|
703
|
+
- Capture system-level events
|
|
704
|
+
|
|
705
|
+
---
|
|
706
|
+
|
|
707
|
+
## 💡 Tips for CI/CD
|
|
708
|
+
|
|
709
|
+
### 1. Always Use `if: always()` in CI
|
|
710
|
+
|
|
711
|
+
```yaml
|
|
712
|
+
# GitHub Actions - Always upload recording
|
|
713
|
+
- name: Stop recording
|
|
714
|
+
if: always()
|
|
715
|
+
run: dashcam stop
|
|
175
716
|
```
|
|
176
717
|
|
|
177
|
-
###
|
|
718
|
+
### 2. Set Proper Timeouts
|
|
178
719
|
|
|
179
|
-
```
|
|
180
|
-
|
|
720
|
+
```bash
|
|
721
|
+
# Give recording time to initialize
|
|
722
|
+
dashcam record --title "Tests" &
|
|
723
|
+
sleep 2 # Important!
|
|
724
|
+
npm test
|
|
181
725
|
```
|
|
182
726
|
|
|
183
|
-
|
|
727
|
+
### 3. Use Descriptive Titles
|
|
184
728
|
|
|
729
|
+
```bash
|
|
730
|
+
# Include branch, commit, or build number
|
|
731
|
+
dashcam record --title "E2E Tests - ${GITHUB_SHA}" \
|
|
732
|
+
--description "Branch: ${GITHUB_REF_NAME}"
|
|
185
733
|
```
|
|
186
|
-
Usage: dashcam create [options]
|
|
187
734
|
|
|
188
|
-
|
|
735
|
+
### 4. Organize with Projects
|
|
189
736
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
--md Returns code for a rich markdown image link.
|
|
194
|
-
-h, --help display help for command
|
|
737
|
+
```bash
|
|
738
|
+
# Group recordings by project
|
|
739
|
+
dashcam record --project $DASHCAM_PROJECT_ID
|
|
195
740
|
```
|
|
196
741
|
|
|
197
|
-
|
|
742
|
+
### 5. Handle Failed Tests Gracefully
|
|
198
743
|
|
|
199
|
-
|
|
744
|
+
```bash
|
|
745
|
+
# Bash script with proper error handling
|
|
746
|
+
set -e
|
|
747
|
+
dashcam record --title "Tests" &
|
|
748
|
+
sleep 2
|
|
200
749
|
|
|
201
|
-
|
|
750
|
+
# Tests might fail, but still upload
|
|
751
|
+
npm test || TEST_FAILED=true
|
|
202
752
|
|
|
203
|
-
|
|
753
|
+
dashcam stop
|
|
204
754
|
|
|
205
|
-
|
|
206
|
-
|
|
755
|
+
# Exit with test status
|
|
756
|
+
if [ "$TEST_FAILED" = true ]; then
|
|
757
|
+
exit 1
|
|
758
|
+
fi
|
|
207
759
|
```
|
|
208
760
|
|
|
209
|
-
|
|
761
|
+
---
|
|
210
762
|
|
|
211
|
-
|
|
212
|
-
window.onerror = function myErrorHandler() {
|
|
213
|
-
window.open("dashcam://replay/create", "_blank");
|
|
214
|
-
};
|
|
763
|
+
## 🗂️ Project Structure
|
|
215
764
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
765
|
+
```
|
|
766
|
+
dashcam/
|
|
767
|
+
├── bin/
|
|
768
|
+
│ └── dashcam.js # CLI entry point
|
|
769
|
+
├── lib/
|
|
770
|
+
│ ├── auth.js # Authentication
|
|
771
|
+
│ ├── recorder.js # Screen recording engine
|
|
772
|
+
│ ├── uploader.js # Cloud upload
|
|
773
|
+
│ ├── processManager.js # Background process handling
|
|
774
|
+
│ ├── logs/ # Log tracking core
|
|
775
|
+
│ ├── tracking/ # File & activity tracking
|
|
776
|
+
│ ├── extension-logs/ # Browser extension integration
|
|
777
|
+
│ └── websocket/ # WebSocket server
|
|
778
|
+
└── examples/ # Example scripts
|
|
219
779
|
```
|
|
220
780
|
|
|
221
|
-
|
|
781
|
+
---
|
|
222
782
|
|
|
223
|
-
|
|
783
|
+
## 🤝 Contributing
|
|
224
784
|
|
|
225
|
-
|
|
226
|
-
npm install dashcam
|
|
227
|
-
```
|
|
785
|
+
We love contributions! Here's how you can help:
|
|
228
786
|
|
|
229
|
-
|
|
787
|
+
1. 🐛 **Report bugs** via GitHub issues
|
|
788
|
+
2. 💡 **Suggest features** we should build
|
|
789
|
+
3. 🔧 **Submit PRs** with improvements
|
|
790
|
+
4. 📖 **Improve docs** for clarity
|
|
230
791
|
|
|
231
|
-
|
|
232
|
-
const dashcam = require("dashcam");
|
|
792
|
+
---
|
|
233
793
|
|
|
234
|
-
|
|
235
|
-
title: "My New Replay",
|
|
236
|
-
description: `This **renders markdown** or plaintext in monospace font.`,
|
|
237
|
-
});
|
|
238
|
-
```
|
|
794
|
+
## 📄 License
|
|
239
795
|
|
|
240
|
-
|
|
796
|
+
MIT © TestDriver.ai
|
|
241
797
|
|
|
242
|
-
|
|
243
|
-
const dashcam = require("dashcam");
|
|
798
|
+
---
|
|
244
799
|
|
|
245
|
-
|
|
246
|
-
let replay = await dashcam.createReplay({
|
|
247
|
-
title: "uncaughtException",
|
|
248
|
-
description: err,
|
|
249
|
-
});
|
|
250
|
-
console.log("Dashcam", replay);
|
|
251
|
-
});
|
|
800
|
+
## 🔗 Links
|
|
252
801
|
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
802
|
+
- **Documentation**: [Full Guide](./LOG_TRACKING_GUIDE.md)
|
|
803
|
+
- **Issues**: [GitHub Issues](https://github.com/testdriverai/dashcam/issues)
|
|
804
|
+
- **Website**: [testdriver.ai](https://testdriver.ai)
|
|
805
|
+
|
|
806
|
+
---
|
|
807
|
+
|
|
808
|
+
<div align="center">
|
|
809
|
+
|
|
810
|
+
**Made with ❤️ by the TestDriver.ai team**
|
|
257
811
|
|
|
258
|
-
|
|
812
|
+
[⭐ Star us on GitHub](https://github.com/testdriverai/dashcam) • [🐦 Follow us on Twitter](https://twitter.com/testdriverai)
|
|
259
813
|
|
|
260
|
-
|
|
814
|
+
</div>
|