node-mac-recorder 2.4.11 ā 2.4.13
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/binding.gyp +5 -12
- package/index.js +25 -104
- package/install.js +2 -19
- package/package.json +2 -6
- package/src/audio_capture.mm +40 -96
- package/src/cursor_tracker.mm +4 -3
- package/src/mac_recorder.mm +673 -753
- package/src/screen_capture.h +0 -5
- package/src/screen_capture.mm +60 -139
- package/src/window_selector.mm +113 -399
- package/window-selector.js +34 -112
- package/ELECTRON-INTEGRATION.md +0 -710
- package/WINDOW_SELECTOR_USAGE.md +0 -447
- package/backup/binding.gyp +0 -44
- package/backup/src/audio_capture.mm +0 -116
- package/backup/src/cursor_tracker.mm +0 -518
- package/backup/src/mac_recorder.mm +0 -829
- package/backup/src/screen_capture.h +0 -19
- package/backup/src/screen_capture.mm +0 -162
- package/backup/src/screen_capture_kit.h +0 -15
- package/backup/src/window_selector.mm +0 -1457
- package/electron-window-selector.js +0 -698
- package/node-mac-recorder-2.4.2.tgz +0 -0
- package/prebuilds/darwin-arm64/node.napi.node +0 -0
- package/test-api-compatibility.js +0 -92
- package/test-audio.js +0 -94
- package/test-comprehensive.js +0 -164
- package/test-electron-window-selector.js +0 -119
- package/test-overlay-fix.js +0 -72
- package/test-recording.js +0 -142
- package/test-sck-availability.js +0 -26
- package/test-sck-simple.js +0 -37
- package/test-sck.js +0 -56
- package/test-screencapture-overlay.js +0 -54
- package/test-simple-windows.js +0 -29
- package/test-sync.js +0 -52
- package/test-window-details.js +0 -34
- package/test-windows.js +0 -57
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
const MacRecorder = require('./index');
|
|
2
|
-
|
|
3
|
-
function testAPICompatibility() {
|
|
4
|
-
console.log('š Testing API Compatibility\n');
|
|
5
|
-
console.log('Verifying that existing packages won\'t break...\n');
|
|
6
|
-
|
|
7
|
-
const recorder = new MacRecorder();
|
|
8
|
-
let compatibilityScore = 0;
|
|
9
|
-
let totalTests = 0;
|
|
10
|
-
|
|
11
|
-
function testAPI(apiName, expectedType, testFunction) {
|
|
12
|
-
totalTests++;
|
|
13
|
-
console.log(`Testing ${apiName}...`);
|
|
14
|
-
|
|
15
|
-
try {
|
|
16
|
-
const result = testFunction();
|
|
17
|
-
if (typeof result === expectedType || result === true) {
|
|
18
|
-
console.log(` ā
${apiName}: Compatible`);
|
|
19
|
-
compatibilityScore++;
|
|
20
|
-
return true;
|
|
21
|
-
} else {
|
|
22
|
-
console.log(` ā ${apiName}: Expected ${expectedType}, got ${typeof result}`);
|
|
23
|
-
return false;
|
|
24
|
-
}
|
|
25
|
-
} catch (error) {
|
|
26
|
-
console.log(` ā ļø ${apiName}: ${error.message}`);
|
|
27
|
-
return false;
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
console.log('š Constructor and Basic Setup:');
|
|
32
|
-
console.log('āāāāāāāāāāāāāāāāāāāāāāāāāāāāāā');
|
|
33
|
-
testAPI('MacRecorder Constructor', 'object', () => new MacRecorder());
|
|
34
|
-
testAPI('Method Existence Check', 'boolean', () => {
|
|
35
|
-
const methods = ['getDisplays', 'getWindows', 'getAudioDevices', 'startRecording',
|
|
36
|
-
'stopRecording', 'checkPermissions', 'getCursorPosition'];
|
|
37
|
-
return methods.every(method => typeof recorder[method] === 'function');
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
console.log('\nš±ļø Cursor Operations (Sync):');
|
|
41
|
-
console.log('āāāāāāāāāāāāāāāāāāāāāāāāāāāā');
|
|
42
|
-
testAPI('getCurrentCursorPosition()', 'object', () => recorder.getCurrentCursorPosition());
|
|
43
|
-
testAPI('getCursorCaptureStatus()', 'object', () => recorder.getCursorCaptureStatus());
|
|
44
|
-
|
|
45
|
-
console.log('\nāļø Configuration Methods:');
|
|
46
|
-
console.log('āāāāāāāāāāāāāāāāāāāāāāāāā');
|
|
47
|
-
testAPI('setOptions()', 'undefined', () => recorder.setOptions({}));
|
|
48
|
-
testAPI('getModuleInfo()', 'object', () => recorder.getModuleInfo());
|
|
49
|
-
|
|
50
|
-
console.log('\nšÆ Compatibility Test Results:');
|
|
51
|
-
console.log('ā'.repeat(50));
|
|
52
|
-
|
|
53
|
-
const percentage = Math.round((compatibilityScore / totalTests) * 100);
|
|
54
|
-
console.log(`ā
Compatible APIs: ${compatibilityScore}/${totalTests}`);
|
|
55
|
-
console.log(`š Compatibility Score: ${percentage}%`);
|
|
56
|
-
|
|
57
|
-
if (percentage >= 90) {
|
|
58
|
-
console.log('\nš EXCELLENT COMPATIBILITY!');
|
|
59
|
-
console.log('⨠Existing packages should work without any changes');
|
|
60
|
-
} else if (percentage >= 75) {
|
|
61
|
-
console.log('\nš GOOD COMPATIBILITY');
|
|
62
|
-
console.log('⨠Most existing packages should work with minimal adjustments');
|
|
63
|
-
} else {
|
|
64
|
-
console.log('\nā ļø COMPATIBILITY ISSUES DETECTED');
|
|
65
|
-
console.log('š§ Some existing packages may need updates');
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
console.log('\nš API Test Summary:');
|
|
69
|
-
console.log('ā'.repeat(40));
|
|
70
|
-
console.log('ā
Constructor: Working');
|
|
71
|
-
console.log('ā
All expected methods: Present');
|
|
72
|
-
console.log('ā
Synchronous operations: Fully compatible');
|
|
73
|
-
console.log('ā ļø Asynchronous operations: Need screen recording permissions');
|
|
74
|
-
|
|
75
|
-
console.log('\nš Migration Status:');
|
|
76
|
-
console.log('ā'.repeat(40));
|
|
77
|
-
console.log('ā
Native module: Built successfully for arm64');
|
|
78
|
-
console.log('ā
ScreenCaptureKit: Integrated and functional');
|
|
79
|
-
console.log('ā
Error handling: Improved (no more crashes)');
|
|
80
|
-
console.log('ā
API surface: 100% preserved');
|
|
81
|
-
console.log('ā ļø Permission handling: Requires user setup');
|
|
82
|
-
|
|
83
|
-
console.log('\nš For Complete Functionality:');
|
|
84
|
-
console.log('ā'.repeat(40));
|
|
85
|
-
console.log('1. Grant screen recording permissions in System Preferences');
|
|
86
|
-
console.log('2. Ensure macOS 12.3+ on ARM64 (Apple Silicon)');
|
|
87
|
-
console.log('3. Test with actual screen recording workflow');
|
|
88
|
-
|
|
89
|
-
console.log(`\nšÆ Overall Migration Success: ${percentage >= 75 ? 'SUCCESSFUL' : 'NEEDS ATTENTION'} āØ`);
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
testAPICompatibility();
|
package/test-audio.js
DELETED
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
const MacRecorder = require('./index');
|
|
2
|
-
|
|
3
|
-
function testAudioCapture() {
|
|
4
|
-
console.log('šµ Testing ScreenCaptureKit Audio Capture...\n');
|
|
5
|
-
|
|
6
|
-
const recorder = new MacRecorder();
|
|
7
|
-
let testCompleted = false;
|
|
8
|
-
|
|
9
|
-
// Set timeout to prevent hanging
|
|
10
|
-
setTimeout(() => {
|
|
11
|
-
if (!testCompleted) {
|
|
12
|
-
console.log('ā ļø Test timed out after 10 seconds');
|
|
13
|
-
process.exit(0);
|
|
14
|
-
}
|
|
15
|
-
}, 10000);
|
|
16
|
-
|
|
17
|
-
try {
|
|
18
|
-
console.log('š± Testing audio device enumeration...');
|
|
19
|
-
|
|
20
|
-
// Test audio device enumeration - this should work without permissions
|
|
21
|
-
const startTime = Date.now();
|
|
22
|
-
|
|
23
|
-
recorder.getAudioDevices((err, audioDevices) => {
|
|
24
|
-
const elapsed = Date.now() - startTime;
|
|
25
|
-
console.log(`ā±ļø getAudioDevices took ${elapsed}ms`);
|
|
26
|
-
|
|
27
|
-
if (err) {
|
|
28
|
-
console.error('ā getAudioDevices failed:', err);
|
|
29
|
-
testCompleted = true;
|
|
30
|
-
return;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
console.log(`ā
Found ${audioDevices.length} audio devices:`);
|
|
34
|
-
|
|
35
|
-
audioDevices.slice(0, 5).forEach((device, index) => {
|
|
36
|
-
console.log(`${index + 1}. "${device.name}" (${device.manufacturer || 'Unknown'})`);
|
|
37
|
-
console.log(` ID: ${device.id}`);
|
|
38
|
-
console.log(` Default: ${device.isDefault ? 'Yes' : 'No'}`);
|
|
39
|
-
if (device.isSystemDevice) {
|
|
40
|
-
console.log(` System Device: ${device.isSystemDevice ? 'Yes' : 'No'}`);
|
|
41
|
-
}
|
|
42
|
-
console.log('');
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
// Test permissions
|
|
46
|
-
console.log('š Testing audio permissions...');
|
|
47
|
-
|
|
48
|
-
recorder.checkPermissions((err, hasPermissions) => {
|
|
49
|
-
const elapsed2 = Date.now() - startTime;
|
|
50
|
-
console.log(`ā±ļø checkPermissions took ${elapsed2 - elapsed}ms`);
|
|
51
|
-
|
|
52
|
-
if (err) {
|
|
53
|
-
console.error('ā checkPermissions failed:', err);
|
|
54
|
-
} else {
|
|
55
|
-
console.log(`ā
Permissions status: ${hasPermissions ? 'Granted' : 'Not granted'}`);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
// Test microphone-specific features if available
|
|
59
|
-
if (audioDevices.length > 0) {
|
|
60
|
-
const micDevice = audioDevices.find(d => d.isDefault && !d.isSystemDevice);
|
|
61
|
-
const systemDevice = audioDevices.find(d => d.isSystemDevice);
|
|
62
|
-
|
|
63
|
-
if (micDevice) {
|
|
64
|
-
console.log(`š¤ Default microphone: "${micDevice.name}"`);
|
|
65
|
-
console.log(` This would be used for includeMicrophone: true`);
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
if (systemDevice) {
|
|
69
|
-
console.log(`š System audio device found: "${systemDevice.name}"`);
|
|
70
|
-
console.log(` This would be used for includeSystemAudio: true`);
|
|
71
|
-
} else {
|
|
72
|
-
console.log('ā ļø No system audio device detected');
|
|
73
|
-
console.log(' For system audio capture, consider installing BlackHole or similar');
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
console.log('\nā
Audio capture tests completed successfully!');
|
|
78
|
-
console.log('\nš Audio Configuration Summary:');
|
|
79
|
-
console.log(` ⢠Total audio devices: ${audioDevices.length}`);
|
|
80
|
-
console.log(` ⢠Microphone devices: ${audioDevices.filter(d => !d.isSystemDevice).length}`);
|
|
81
|
-
console.log(` ⢠System audio devices: ${audioDevices.filter(d => d.isSystemDevice).length}`);
|
|
82
|
-
console.log(` ⢠Permissions: ${hasPermissions ? 'ā
Granted' : 'ā Need to grant'}`);
|
|
83
|
-
|
|
84
|
-
testCompleted = true;
|
|
85
|
-
});
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
} catch (error) {
|
|
89
|
-
console.error('ā Audio capture test failed:', error);
|
|
90
|
-
testCompleted = true;
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
testAudioCapture();
|
package/test-comprehensive.js
DELETED
|
@@ -1,164 +0,0 @@
|
|
|
1
|
-
const MacRecorder = require('./index');
|
|
2
|
-
const fs = require('fs');
|
|
3
|
-
const path = require('path');
|
|
4
|
-
|
|
5
|
-
function runComprehensiveTests() {
|
|
6
|
-
console.log('š§Ŗ Running Comprehensive ScreenCaptureKit Tests\n');
|
|
7
|
-
console.log('=' .repeat(60));
|
|
8
|
-
|
|
9
|
-
const recorder = new MacRecorder();
|
|
10
|
-
let testResults = {
|
|
11
|
-
passed: 0,
|
|
12
|
-
failed: 0,
|
|
13
|
-
details: []
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
function addResult(testName, passed, details = '') {
|
|
17
|
-
testResults.details.push({
|
|
18
|
-
name: testName,
|
|
19
|
-
passed,
|
|
20
|
-
details
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
if (passed) {
|
|
24
|
-
testResults.passed++;
|
|
25
|
-
console.log(`ā
${testName}`);
|
|
26
|
-
} else {
|
|
27
|
-
testResults.failed++;
|
|
28
|
-
console.log(`ā ${testName}: ${details}`);
|
|
29
|
-
}
|
|
30
|
-
if (details && passed) {
|
|
31
|
-
console.log(` ${details}`);
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
// Test 1: Module Loading
|
|
36
|
-
try {
|
|
37
|
-
addResult('Module Loading', true, 'MacRecorder class instantiated successfully');
|
|
38
|
-
} catch (error) {
|
|
39
|
-
addResult('Module Loading', false, error.message);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
// Test 2: Method Availability
|
|
43
|
-
const expectedMethods = [
|
|
44
|
-
'getDisplays', 'getWindows', 'getAudioDevices', 'startRecording',
|
|
45
|
-
'stopRecording', 'checkPermissions', 'getCursorPosition',
|
|
46
|
-
'getWindowThumbnail', 'getDisplayThumbnail'
|
|
47
|
-
];
|
|
48
|
-
|
|
49
|
-
let missingMethods = [];
|
|
50
|
-
expectedMethods.forEach(method => {
|
|
51
|
-
if (typeof recorder[method] !== 'function') {
|
|
52
|
-
missingMethods.push(method);
|
|
53
|
-
}
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
if (missingMethods.length === 0) {
|
|
57
|
-
addResult('API Method Availability', true, `All ${expectedMethods.length} expected methods available`);
|
|
58
|
-
} else {
|
|
59
|
-
addResult('API Method Availability', false, `Missing methods: ${missingMethods.join(', ')}`);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
// Test 3: Synchronous Operations
|
|
63
|
-
try {
|
|
64
|
-
const cursor = recorder.getCurrentCursorPosition();
|
|
65
|
-
if (cursor && typeof cursor.x === 'number' && typeof cursor.y === 'number') {
|
|
66
|
-
addResult('Cursor Position (Sync)', true, `Position: (${cursor.x}, ${cursor.y}), Type: ${cursor.cursorType}`);
|
|
67
|
-
} else {
|
|
68
|
-
addResult('Cursor Position (Sync)', false, 'Invalid cursor data returned');
|
|
69
|
-
}
|
|
70
|
-
} catch (error) {
|
|
71
|
-
addResult('Cursor Position (Sync)', false, error.message);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
// Test 4: Cursor Capture Status
|
|
75
|
-
try {
|
|
76
|
-
const status = recorder.getCursorCaptureStatus();
|
|
77
|
-
addResult('Cursor Capture Status', true, `Tracking: ${status.isTracking || false}`);
|
|
78
|
-
} catch (error) {
|
|
79
|
-
addResult('Cursor Capture Status', false, error.message);
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
console.log('\n' + 'ā'.repeat(60));
|
|
83
|
-
console.log('š Test Results Summary:');
|
|
84
|
-
console.log('ā'.repeat(60));
|
|
85
|
-
console.log(`ā
Passed: ${testResults.passed}`);
|
|
86
|
-
console.log(`ā Failed: ${testResults.failed}`);
|
|
87
|
-
console.log(`š Success Rate: ${Math.round((testResults.passed / (testResults.passed + testResults.failed)) * 100)}%`);
|
|
88
|
-
|
|
89
|
-
console.log('\nš Detailed Analysis:');
|
|
90
|
-
console.log('ā'.repeat(60));
|
|
91
|
-
|
|
92
|
-
// Test async operations with timeout
|
|
93
|
-
console.log('\nš Testing Async Operations (with 8s timeout each):');
|
|
94
|
-
|
|
95
|
-
let asyncTests = 0;
|
|
96
|
-
let asyncPassed = 0;
|
|
97
|
-
|
|
98
|
-
function testAsync(testName, asyncFunction, timeout = 8000) {
|
|
99
|
-
return new Promise((resolve) => {
|
|
100
|
-
asyncTests++;
|
|
101
|
-
const timeoutId = setTimeout(() => {
|
|
102
|
-
console.log(`ā ļø ${testName}: Timed out after ${timeout/1000}s (likely permission dialog)`);
|
|
103
|
-
resolve(false);
|
|
104
|
-
}, timeout);
|
|
105
|
-
|
|
106
|
-
try {
|
|
107
|
-
asyncFunction((error, result) => {
|
|
108
|
-
clearTimeout(timeoutId);
|
|
109
|
-
if (error) {
|
|
110
|
-
console.log(`ā ${testName}: ${error.message || error}`);
|
|
111
|
-
resolve(false);
|
|
112
|
-
} else {
|
|
113
|
-
const resultInfo = Array.isArray(result) ? `${result.length} items` : 'Success';
|
|
114
|
-
console.log(`ā
${testName}: ${resultInfo}`);
|
|
115
|
-
asyncPassed++;
|
|
116
|
-
resolve(true);
|
|
117
|
-
}
|
|
118
|
-
});
|
|
119
|
-
} catch (error) {
|
|
120
|
-
clearTimeout(timeoutId);
|
|
121
|
-
console.log(`ā ${testName}: ${error.message}`);
|
|
122
|
-
resolve(false);
|
|
123
|
-
}
|
|
124
|
-
});
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
// Run async tests sequentially
|
|
128
|
-
(async () => {
|
|
129
|
-
await testAsync('Permissions Check', (cb) => recorder.checkPermissions(cb));
|
|
130
|
-
await testAsync('Display Enumeration', (cb) => recorder.getDisplays(cb));
|
|
131
|
-
await testAsync('Window Enumeration', (cb) => recorder.getWindows(cb));
|
|
132
|
-
await testAsync('Audio Device Enumeration', (cb) => recorder.getAudioDevices(cb));
|
|
133
|
-
|
|
134
|
-
console.log('\n' + 'ā'.repeat(60));
|
|
135
|
-
console.log('š Final Test Summary:');
|
|
136
|
-
console.log('ā'.repeat(60));
|
|
137
|
-
console.log(`š§ Synchronous Tests: ${testResults.passed}/${testResults.passed + testResults.failed} passed`);
|
|
138
|
-
console.log(`š Asynchronous Tests: ${asyncPassed}/${asyncTests} passed`);
|
|
139
|
-
console.log(`š Overall: ${testResults.passed + asyncPassed}/${testResults.passed + testResults.failed + asyncTests} tests passed`);
|
|
140
|
-
|
|
141
|
-
const overallSuccess = Math.round(((testResults.passed + asyncPassed) / (testResults.passed + testResults.failed + asyncTests)) * 100);
|
|
142
|
-
|
|
143
|
-
if (overallSuccess >= 80) {
|
|
144
|
-
console.log(`\nš ScreenCaptureKit Migration: ${overallSuccess}% SUCCESS!`);
|
|
145
|
-
console.log('⨠The migration is working correctly');
|
|
146
|
-
} else if (overallSuccess >= 60) {
|
|
147
|
-
console.log(`\nā ļø ScreenCaptureKit Migration: ${overallSuccess}% PARTIAL SUCCESS`);
|
|
148
|
-
console.log('š§ Some functionality working, permissions may need attention');
|
|
149
|
-
} else {
|
|
150
|
-
console.log(`\nā ScreenCaptureKit Migration: ${overallSuccess}% - NEEDS WORK`);
|
|
151
|
-
console.log('šØ Multiple issues detected');
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
console.log('\nš” Notes:');
|
|
155
|
-
console.log('⢠Timeouts usually indicate missing screen recording permissions');
|
|
156
|
-
console.log('⢠Enable permissions in: System Preferences > Privacy & Security > Screen Recording');
|
|
157
|
-
console.log('⢠ScreenCaptureKit requires macOS 12.3+ and arm64 architecture');
|
|
158
|
-
console.log('⢠All synchronous operations (cursor tracking) should work without permissions');
|
|
159
|
-
|
|
160
|
-
process.exit(0);
|
|
161
|
-
})();
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
runComprehensiveTests();
|
|
@@ -1,119 +0,0 @@
|
|
|
1
|
-
const ElectronWindowSelector = require('./electron-window-selector');
|
|
2
|
-
|
|
3
|
-
// Electron environment simülasyonu
|
|
4
|
-
console.log('š§Ŗ Testing Electron Window Selector...\n');
|
|
5
|
-
|
|
6
|
-
// Electron environment variable'ları set et
|
|
7
|
-
process.env.ELECTRON_VERSION = '25.0.0';
|
|
8
|
-
|
|
9
|
-
async function testElectronWindowSelector() {
|
|
10
|
-
const selector = new ElectronWindowSelector();
|
|
11
|
-
|
|
12
|
-
console.log(`š Environment: ${selector.isElectron ? 'Electron' : 'Node.js'}`);
|
|
13
|
-
|
|
14
|
-
try {
|
|
15
|
-
console.log('\n1ļøā£ Testing Permission Check...');
|
|
16
|
-
const permissions = await selector.checkPermissions();
|
|
17
|
-
console.log('ā
Permissions:', permissions);
|
|
18
|
-
|
|
19
|
-
console.log('\n2ļøā£ Testing Available Windows...');
|
|
20
|
-
const windows = await selector.getAvailableWindows();
|
|
21
|
-
console.log(`ā
Found ${windows.length} windows`);
|
|
22
|
-
if (windows.length > 0) {
|
|
23
|
-
console.log(' š± Sample window:', {
|
|
24
|
-
title: windows[0].title,
|
|
25
|
-
appName: windows[0].appName,
|
|
26
|
-
size: `${windows[0].width}x${windows[0].height}`
|
|
27
|
-
});
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
console.log('\n3ļøā£ Testing Available Displays...');
|
|
31
|
-
const displays = await selector.getAvailableDisplays();
|
|
32
|
-
console.log(`ā
Found ${displays.length} displays`);
|
|
33
|
-
if (displays.length > 0) {
|
|
34
|
-
console.log(' š„ļø Primary display:', {
|
|
35
|
-
name: displays[0].name,
|
|
36
|
-
resolution: `${displays[0].width}x${displays[0].height}`,
|
|
37
|
-
isPrimary: displays[0].isPrimary
|
|
38
|
-
});
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
console.log('\n4ļøā£ Testing Window Selection (Electron Safe Mode)...');
|
|
42
|
-
const windowSelectionPromise = selector.selectWindow();
|
|
43
|
-
|
|
44
|
-
// Event listeners
|
|
45
|
-
selector.on('windowSelected', (windowInfo) => {
|
|
46
|
-
console.log('šÆ Window selected event:', {
|
|
47
|
-
title: windowInfo.title,
|
|
48
|
-
appName: windowInfo.appName,
|
|
49
|
-
position: `${windowInfo.x},${windowInfo.y}`,
|
|
50
|
-
size: `${windowInfo.width}x${windowInfo.height}`
|
|
51
|
-
});
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
selector.on('selectionStarted', () => {
|
|
55
|
-
console.log('š¢ Window selection started');
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
const selectedWindow = await windowSelectionPromise;
|
|
59
|
-
console.log('ā
Window selection completed');
|
|
60
|
-
|
|
61
|
-
console.log('\n5ļøā£ Testing Screen Selection (Electron Safe Mode)...');
|
|
62
|
-
const screenSelectionPromise = selector.selectScreen();
|
|
63
|
-
|
|
64
|
-
selector.on('screenSelected', (screenInfo) => {
|
|
65
|
-
console.log('š„ļø Screen selected event:', {
|
|
66
|
-
name: screenInfo.name || 'Display ' + screenInfo.id,
|
|
67
|
-
resolution: `${screenInfo.width}x${screenInfo.height}`,
|
|
68
|
-
isPrimary: screenInfo.isPrimary
|
|
69
|
-
});
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
const selectedScreen = await screenSelectionPromise;
|
|
73
|
-
console.log('ā
Screen selection completed');
|
|
74
|
-
|
|
75
|
-
console.log('\n6ļøā£ Testing Recording Preview (Electron Safe Mode)...');
|
|
76
|
-
if (selectedWindow) {
|
|
77
|
-
await selector.showRecordingPreview(selectedWindow);
|
|
78
|
-
console.log('ā
Recording preview shown (Electron mode - no native overlay)');
|
|
79
|
-
|
|
80
|
-
await selector.hideRecordingPreview();
|
|
81
|
-
console.log('ā
Recording preview hidden');
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
console.log('\n7ļøā£ Testing Screen Recording Preview (Electron Safe Mode)...');
|
|
85
|
-
if (selectedScreen) {
|
|
86
|
-
await selector.showScreenRecordingPreview(selectedScreen);
|
|
87
|
-
console.log('ā
Screen recording preview shown (Electron mode - no native overlay)');
|
|
88
|
-
|
|
89
|
-
await selector.hideScreenRecordingPreview();
|
|
90
|
-
console.log('ā
Screen recording preview hidden');
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
console.log('\n8ļøā£ Cleanup...');
|
|
94
|
-
await selector.cleanup();
|
|
95
|
-
console.log('ā
Cleanup completed');
|
|
96
|
-
|
|
97
|
-
console.log('\nš All Electron Window Selector tests PASSED!');
|
|
98
|
-
|
|
99
|
-
} catch (error) {
|
|
100
|
-
console.error('\nā Test failed:', error.message);
|
|
101
|
-
console.error(' Stack:', error.stack);
|
|
102
|
-
|
|
103
|
-
// Cleanup on error
|
|
104
|
-
try {
|
|
105
|
-
await selector.cleanup();
|
|
106
|
-
} catch (cleanupError) {
|
|
107
|
-
console.error('ā Cleanup failed:', cleanupError.message);
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
// Run test
|
|
113
|
-
testElectronWindowSelector().then(() => {
|
|
114
|
-
console.log('\nā
Test completed');
|
|
115
|
-
process.exit(0);
|
|
116
|
-
}).catch((error) => {
|
|
117
|
-
console.error('\nā Test suite failed:', error);
|
|
118
|
-
process.exit(1);
|
|
119
|
-
});
|
package/test-overlay-fix.js
DELETED
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
const ElectronWindowSelector = require('./electron-window-selector.js');
|
|
4
|
-
|
|
5
|
-
console.log('š§Ŗ Testing Fixed Overlay Functionality');
|
|
6
|
-
console.log('=====================================');
|
|
7
|
-
|
|
8
|
-
async function testOverlayFunctionality() {
|
|
9
|
-
const selector = new ElectronWindowSelector();
|
|
10
|
-
|
|
11
|
-
try {
|
|
12
|
-
console.log('\nš Environment Check:');
|
|
13
|
-
const status = selector.getStatus();
|
|
14
|
-
console.log(` - Electron Mode: ${status.isElectron}`);
|
|
15
|
-
|
|
16
|
-
console.log('\nšŖ Testing Window Detection...');
|
|
17
|
-
|
|
18
|
-
// Test real-time window detection
|
|
19
|
-
console.log('Move your mouse over different windows...');
|
|
20
|
-
console.log('Press Ctrl+C to stop\n');
|
|
21
|
-
|
|
22
|
-
let lastWindowId = null;
|
|
23
|
-
|
|
24
|
-
const checkInterval = setInterval(async () => {
|
|
25
|
-
try {
|
|
26
|
-
// Simulate what Electron app would do - poll for current window
|
|
27
|
-
const windowStatus = require('./build/Release/mac_recorder.node').getWindowSelectionStatus();
|
|
28
|
-
|
|
29
|
-
if (windowStatus && windowStatus.currentWindow) {
|
|
30
|
-
const window = windowStatus.currentWindow;
|
|
31
|
-
|
|
32
|
-
if (window.id !== lastWindowId) {
|
|
33
|
-
lastWindowId = window.id;
|
|
34
|
-
|
|
35
|
-
console.log(`šÆ Window Detected: ${window.appName} - "${window.title}"`);
|
|
36
|
-
console.log(` š Position: (${window.x}, ${window.y})`);
|
|
37
|
-
console.log(` š Size: ${window.width}x${window.height}`);
|
|
38
|
-
|
|
39
|
-
if (window.screenId !== undefined) {
|
|
40
|
-
console.log(` š„ļø Screen: ${window.screenId} (${window.screenWidth}x${window.screenHeight})`);
|
|
41
|
-
}
|
|
42
|
-
console.log('');
|
|
43
|
-
}
|
|
44
|
-
} else if (lastWindowId !== null) {
|
|
45
|
-
lastWindowId = null;
|
|
46
|
-
console.log('šŖ No window under cursor\n');
|
|
47
|
-
}
|
|
48
|
-
} catch (error) {
|
|
49
|
-
console.error('Error during window detection:', error.message);
|
|
50
|
-
}
|
|
51
|
-
}, 100); // Check every 100ms for smooth tracking
|
|
52
|
-
|
|
53
|
-
// Handle Ctrl+C gracefully
|
|
54
|
-
process.on('SIGINT', () => {
|
|
55
|
-
console.log('\n\nš Stopping test...');
|
|
56
|
-
clearInterval(checkInterval);
|
|
57
|
-
selector.cleanup().then(() => {
|
|
58
|
-
console.log('ā
Cleanup completed');
|
|
59
|
-
process.exit(0);
|
|
60
|
-
});
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
} catch (error) {
|
|
64
|
-
console.error('ā Test failed:', error.message);
|
|
65
|
-
process.exit(1);
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
// Set Electron environment for testing
|
|
70
|
-
process.env.ELECTRON_VERSION = '25.0.0';
|
|
71
|
-
|
|
72
|
-
testOverlayFunctionality();
|
package/test-recording.js
DELETED
|
@@ -1,142 +0,0 @@
|
|
|
1
|
-
const MacRecorder = require("./index");
|
|
2
|
-
const path = require("path");
|
|
3
|
-
const fs = require("fs");
|
|
4
|
-
|
|
5
|
-
async function testRecording() {
|
|
6
|
-
console.log("š¬ Testing ScreenCaptureKit Recording...\n");
|
|
7
|
-
|
|
8
|
-
const recorder = new MacRecorder();
|
|
9
|
-
const outputDir = path.join(__dirname, "test-output");
|
|
10
|
-
|
|
11
|
-
// Create test output directory
|
|
12
|
-
if (!fs.existsSync(outputDir)) {
|
|
13
|
-
fs.mkdirSync(outputDir);
|
|
14
|
-
console.log("š Created test-output directory");
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
const outputFile = path.resolve(outputDir, "sck-test-recording.mov");
|
|
18
|
-
console.log(`š¹ Output file: ${outputFile}`);
|
|
19
|
-
|
|
20
|
-
// Test recording options
|
|
21
|
-
const recordingOptions = {
|
|
22
|
-
captureCursor: true,
|
|
23
|
-
excludeCurrentApp: true,
|
|
24
|
-
includeMicrophone: true,
|
|
25
|
-
includeSystemAudio: true, // Disable to avoid permission issues for now
|
|
26
|
-
displayId: null, // Will use main display
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
console.log(
|
|
30
|
-
"š Recording options:",
|
|
31
|
-
JSON.stringify(recordingOptions, null, 2)
|
|
32
|
-
);
|
|
33
|
-
console.log("\nš Starting recording test...");
|
|
34
|
-
|
|
35
|
-
try {
|
|
36
|
-
// Test current cursor position before recording
|
|
37
|
-
const cursor = recorder.getCurrentCursorPosition();
|
|
38
|
-
console.log(
|
|
39
|
-
`š±ļø Current cursor: x=${cursor.x}, y=${cursor.y}, type=${cursor.cursorType}`
|
|
40
|
-
);
|
|
41
|
-
|
|
42
|
-
// Determine a window to exclude (prefer a window with name containing "Cursor")
|
|
43
|
-
try {
|
|
44
|
-
const windows = await recorder.getWindows();
|
|
45
|
-
if (Array.isArray(windows) && windows.length) {
|
|
46
|
-
const pick =
|
|
47
|
-
windows.find(
|
|
48
|
-
(w) =>
|
|
49
|
-
(typeof w.appName === "string" && /cursor/i.test(w.appName)) ||
|
|
50
|
-
(typeof w.name === "string" && /cursor/i.test(w.name)) ||
|
|
51
|
-
(typeof w.title === "string" && /cursor/i.test(w.title))
|
|
52
|
-
) || windows[0];
|
|
53
|
-
const wid = pick?.id ?? pick?.windowId ?? pick?.windowID ?? null;
|
|
54
|
-
if (wid != null) {
|
|
55
|
-
recordingOptions.excludeWindowIds = [Number(wid)];
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
} catch (_) {}
|
|
59
|
-
|
|
60
|
-
// Start recording
|
|
61
|
-
console.log("ā¶ļø Attempting to start recording...");
|
|
62
|
-
|
|
63
|
-
// Start recording without callback first
|
|
64
|
-
console.log("š Attempting startRecording without callback...");
|
|
65
|
-
|
|
66
|
-
let startResult;
|
|
67
|
-
try {
|
|
68
|
-
startResult = await recorder.startRecording(outputFile, recordingOptions);
|
|
69
|
-
console.log(`š startRecording resolved: ${startResult}`);
|
|
70
|
-
} catch (error) {
|
|
71
|
-
console.error("ā startRecording threw error:", error.message);
|
|
72
|
-
console.error("Stack:", error.stack);
|
|
73
|
-
return;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
if (startResult) {
|
|
77
|
-
console.log("ā
Recording started successfully");
|
|
78
|
-
console.log("ā±ļø Recording for 3 seconds...");
|
|
79
|
-
|
|
80
|
-
// Record for ~6 seconds
|
|
81
|
-
setTimeout(async () => {
|
|
82
|
-
console.log("ā¹ļø Stopping recording...");
|
|
83
|
-
|
|
84
|
-
let stopResult;
|
|
85
|
-
try {
|
|
86
|
-
stopResult = await recorder.stopRecording();
|
|
87
|
-
console.log(
|
|
88
|
-
`š stopRecording resolved: ${JSON.stringify(stopResult)}`
|
|
89
|
-
);
|
|
90
|
-
|
|
91
|
-
if (stopResult && stopResult.code === 0) {
|
|
92
|
-
console.log("ā
Stop recording command sent");
|
|
93
|
-
} else {
|
|
94
|
-
console.log("ā Failed to send stop recording command");
|
|
95
|
-
}
|
|
96
|
-
} catch (error) {
|
|
97
|
-
console.error("ā stopRecording threw error:", error.message);
|
|
98
|
-
console.error("Stack:", error.stack);
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
// Final check after a longer delay
|
|
102
|
-
setTimeout(() => {
|
|
103
|
-
console.log("\nš Final Results:");
|
|
104
|
-
|
|
105
|
-
try {
|
|
106
|
-
if (fs.existsSync(outputFile)) {
|
|
107
|
-
const stats = fs.statSync(outputFile);
|
|
108
|
-
console.log(`ā
Recording file exists: ${stats.size} bytes`);
|
|
109
|
-
console.log(`š Location: ${outputFile}`);
|
|
110
|
-
console.log("šÆ ScreenCaptureKit recording test PASSED");
|
|
111
|
-
} else {
|
|
112
|
-
console.log("ā Recording file does not exist");
|
|
113
|
-
console.log(
|
|
114
|
-
"š This might be due to permissions or ScreenCaptureKit configuration"
|
|
115
|
-
);
|
|
116
|
-
}
|
|
117
|
-
} catch (error) {
|
|
118
|
-
console.error("ā Final check error:", error.message);
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
console.log("\nā
Recording test completed");
|
|
122
|
-
}, 4000);
|
|
123
|
-
}, 6000);
|
|
124
|
-
} else {
|
|
125
|
-
console.log("ā Failed to start recording");
|
|
126
|
-
console.log("š Possible causes:");
|
|
127
|
-
console.log(" ⢠Screen recording permissions not granted");
|
|
128
|
-
console.log(" ⢠ScreenCaptureKit not available (requires macOS 12.3+)");
|
|
129
|
-
console.log(" ⢠Display/window selection issues");
|
|
130
|
-
}
|
|
131
|
-
} catch (error) {
|
|
132
|
-
console.error("ā Recording test failed with exception:", error);
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
// Handle process exit
|
|
137
|
-
process.on("SIGINT", () => {
|
|
138
|
-
console.log("\nā ļø Recording test interrupted");
|
|
139
|
-
process.exit(0);
|
|
140
|
-
});
|
|
141
|
-
|
|
142
|
-
testRecording();
|