1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 |
|
23 |
|
24 |
|
25 |
|
26 | exports.defineAutoTests = function () {
|
27 | describe('Capture (navigator.device.capture)', function () {
|
28 | it('capture.spec.1 should exist', function () {
|
29 | expect(navigator.device).toBeDefined();
|
30 | expect(navigator.device.capture).toBeDefined();
|
31 | });
|
32 |
|
33 | it('capture.spec.2 should have the correct properties ', function () {
|
34 | expect(navigator.device.capture.supportedAudioModes).toBeDefined();
|
35 | expect(navigator.device.capture.supportedImageModes).toBeDefined();
|
36 | expect(navigator.device.capture.supportedVideoModes).toBeDefined();
|
37 | });
|
38 |
|
39 | it('capture.spec.3 should contain a captureAudio function', function () {
|
40 | expect(navigator.device.capture.captureAudio).toBeDefined();
|
41 | expect(typeof navigator.device.capture.captureAudio === 'function').toBe(true);
|
42 | });
|
43 |
|
44 | it('capture.spec.4 should contain a captureImage function', function () {
|
45 | expect(navigator.device.capture.captureImage).toBeDefined();
|
46 | expect(typeof navigator.device.capture.captureImage === 'function').toBe(true);
|
47 | });
|
48 |
|
49 | it('capture.spec.5 should contain a captureVideo function', function () {
|
50 | expect(navigator.device.capture.captureVideo).toBeDefined();
|
51 | expect(typeof navigator.device.capture.captureVideo === 'function').toBe(true);
|
52 | });
|
53 |
|
54 | describe('CaptureAudioOptions', function () {
|
55 | it('capture.spec.6 CaptureAudioOptions constructor should exist', function () {
|
56 | var options = new CaptureAudioOptions();
|
57 | expect(options).toBeDefined();
|
58 | expect(options.limit).toBeDefined();
|
59 | expect(options.duration).toBeDefined();
|
60 | });
|
61 | });
|
62 |
|
63 | describe('CaptureImageOptions', function () {
|
64 | it('capture.spec.7 CaptureImageOptions constructor should exist', function () {
|
65 | var options = new CaptureImageOptions();
|
66 | expect(options).toBeDefined();
|
67 | expect(options.limit).toBeDefined();
|
68 | });
|
69 | });
|
70 |
|
71 | describe('CaptureVideoOptions', function () {
|
72 | it('capture.spec.8 CaptureVideoOptions constructor should exist', function () {
|
73 | var options = new CaptureVideoOptions();
|
74 | expect(options).toBeDefined();
|
75 | expect(options.limit).toBeDefined();
|
76 | expect(options.duration).toBeDefined();
|
77 | });
|
78 | });
|
79 |
|
80 | describe('CaptureError interface', function () {
|
81 | it('capture.spec.9 CaptureError constants should be defined', function () {
|
82 | expect(CaptureError.CAPTURE_INTERNAL_ERR).toBe(0);
|
83 | expect(CaptureError.CAPTURE_APPLICATION_BUSY).toBe(1);
|
84 | expect(CaptureError.CAPTURE_INVALID_ARGUMENT).toBe(2);
|
85 | expect(CaptureError.CAPTURE_NO_MEDIA_FILES).toBe(3);
|
86 | });
|
87 |
|
88 | it('capture.spec.10 CaptureError properties should exist', function () {
|
89 | var error = new CaptureError();
|
90 | expect(error).toBeDefined();
|
91 | expect(error.code).toBeDefined();
|
92 | });
|
93 | });
|
94 |
|
95 | describe('MediaFileData', function () {
|
96 | it('capture.spec.11 MediaFileData constructor should exist', function () {
|
97 | var fileData = new MediaFileData();
|
98 | expect(fileData).toBeDefined();
|
99 | expect(fileData.bitrate).toBeDefined();
|
100 | expect(fileData.codecs).toBeDefined();
|
101 | expect(fileData.duration).toBeDefined();
|
102 | expect(fileData.height).toBeDefined();
|
103 | expect(fileData.width).toBeDefined();
|
104 | });
|
105 | });
|
106 |
|
107 | describe('MediaFile', function () {
|
108 | it('capture.spec.12 MediaFile constructor should exist', function () {
|
109 | var fileData = new MediaFile();
|
110 | expect(fileData).toBeDefined();
|
111 | expect(fileData.name).toBeDefined();
|
112 | expect(fileData.type).toBeDefined();
|
113 | expect(fileData.lastModifiedDate).toBeDefined();
|
114 | expect(fileData.size).toBeDefined();
|
115 | });
|
116 | });
|
117 | });
|
118 | };
|
119 |
|
120 |
|
121 |
|
122 |
|
123 |
|
124 | exports.defineManualTests = function (contentEl, createActionButton) {
|
125 | var pageStartTime = +new Date();
|
126 |
|
127 | function log (value) {
|
128 | document.getElementById('camera_status').textContent += (new Date() - pageStartTime) / 1000 + ': ' + value + '\n';
|
129 | console.log(value);
|
130 | }
|
131 |
|
132 | function captureAudioWin (mediaFiles) {
|
133 | var path = mediaFiles[0].fullPath;
|
134 | log('Audio captured: ' + path);
|
135 | var m = new Media(path);
|
136 | m.play();
|
137 | getFileMetadata(mediaFiles[0]);
|
138 | }
|
139 |
|
140 | function captureAudioFail (e) {
|
141 | log('Error getting audio: ' + e.code);
|
142 | }
|
143 |
|
144 | function getAudio () {
|
145 | clearStatus();
|
146 | var options = { limit: 1, duration: 10 };
|
147 | navigator.device.capture.captureAudio(captureAudioWin, captureAudioFail, options);
|
148 | }
|
149 |
|
150 | function captureImageWin (mediaFiles) {
|
151 | var path = mediaFiles[0].fullPath;
|
152 |
|
153 | if (cordova.platformId === 'windows' || cordova.platformId === 'windows8' || cordova.platformId === 'browser') {
|
154 | path = mediaFiles[0].localURL;
|
155 | }
|
156 | log('Image captured: ' + path);
|
157 | document.getElementById('camera_image').src = path;
|
158 | }
|
159 |
|
160 | function captureImagesWin (mediaFiles) {
|
161 | var path = mediaFiles[0].fullPath;
|
162 |
|
163 | if (cordova.platformId === 'windows' || cordova.platformId === 'windows8' || cordova.platformId === 'browser') {
|
164 | path = mediaFiles[0].localURL;
|
165 | }
|
166 | var path2 = mediaFiles[1].fullPath;
|
167 |
|
168 | if (cordova.platformId === 'windows' || cordova.platformId === 'windows8' || cordova.platformId === 'browser') {
|
169 | path = mediaFiles[1].localURL;
|
170 | }
|
171 | var path3 = mediaFiles[2].fullPath;
|
172 |
|
173 | if (cordova.platformId === 'windows' || cordova.platformId === 'windows8' || cordova.platformId === 'browser') {
|
174 | path = mediaFiles[2].localURL;
|
175 | }
|
176 | log('Image captured: ' + path);
|
177 | log('Image captured: ' + path2);
|
178 | log('Image captured: ' + path3);
|
179 | document.getElementById('camera_image').src = path;
|
180 | document.getElementById('camera_image2').src = path2;
|
181 | document.getElementById('camera_image3').src = path3;
|
182 | }
|
183 |
|
184 | function captureImageFail (e) {
|
185 | log('Error getting image: ' + e.code);
|
186 | }
|
187 |
|
188 | function getImage () {
|
189 | clearStatus();
|
190 | var options = { limit: 1 };
|
191 | navigator.device.capture.captureImage(captureImageWin, captureImageFail, options);
|
192 | }
|
193 |
|
194 | function getImages () {
|
195 | clearStatus();
|
196 | var options = { limit: 3 };
|
197 | navigator.device.capture.captureImage(captureImagesWin, captureImageFail, options);
|
198 | }
|
199 |
|
200 | function captureVideoWin (mediaFiles) {
|
201 | var path = mediaFiles[0].fullPath;
|
202 | log('Video captured: ' + path);
|
203 |
|
204 |
|
205 |
|
206 |
|
207 | var vid = document.createElement('video');
|
208 | vid.id = 'theVideo';
|
209 | vid.width = '320';
|
210 | vid.height = '240';
|
211 | vid.controls = 'true';
|
212 | var source_vid = document.createElement('source');
|
213 | source_vid.id = 'theSource';
|
214 | source_vid.src = path;
|
215 | vid.appendChild(source_vid);
|
216 | document.getElementById('video_container').appendChild(vid);
|
217 | getFileMetadata(mediaFiles[0]);
|
218 | }
|
219 |
|
220 | function getFileMetadata (mediaFile) {
|
221 | mediaFile.getFormatData(getMetadataWin, getMetadataFail);
|
222 | }
|
223 |
|
224 | function getMetadataWin (metadata) {
|
225 | var strMetadata =
|
226 | 'duration = ' + metadata.duration + '\n' +
|
227 | 'width = ' + metadata.width + '\n' +
|
228 | 'height = ' + metadata.height;
|
229 | log(strMetadata);
|
230 | }
|
231 |
|
232 | function getMetadataFail (e) {
|
233 | log('Error getting metadata: ' + e.code);
|
234 | }
|
235 |
|
236 | function captureVideoFail (e) {
|
237 | log('Error getting video: ' + e.code);
|
238 | }
|
239 |
|
240 | function getVideo () {
|
241 | clearStatus();
|
242 | var options = { limit: 1, duration: 10 };
|
243 | navigator.device.capture.captureVideo(captureVideoWin, captureVideoFail, options);
|
244 | }
|
245 |
|
246 | function permissionWasNotAllowed () {
|
247 | log('Media has been captured. Have you forgotten to disallow camera for this app?');
|
248 | }
|
249 |
|
250 | function catchPermissionError (error) {
|
251 | if (CaptureError.CAPTURE_PERMISSION_DENIED === error.code) {
|
252 | log('Sucess: permission error has been detected!');
|
253 | } else {
|
254 | log('Error: another error with code: ' + error.code);
|
255 | }
|
256 | }
|
257 |
|
258 | function getVideoPermissionError () {
|
259 | var options = { limit: 1, duration: 10 };
|
260 | navigator.device.capture.captureVideo(permissionWasNotAllowed, catchPermissionError, options);
|
261 | }
|
262 |
|
263 | function getImagePermissionError () {
|
264 | var options = { limit: 1 };
|
265 | navigator.device.capture.captureImage(permissionWasNotAllowed, catchPermissionError, options);
|
266 | }
|
267 |
|
268 | function resolveMediaFileURL (mediaFile, callback) {
|
269 | resolveLocalFileSystemURL(mediaFile.localURL, function (entry) {
|
270 | log('Resolved by URL: ' + mediaFile.localURL);
|
271 | if (callback) callback();
|
272 | }, function (err) {
|
273 | log('Failed to resolve by URL: ' + mediaFile.localURL);
|
274 | log('Error: ' + JSON.stringify(err));
|
275 | if (callback) callback();
|
276 | });
|
277 | }
|
278 |
|
279 | function resolveMediaFile (mediaFile, callback) {
|
280 | resolveLocalFileSystemURL(mediaFile.fullPath, function (entry) {
|
281 | log('Resolved by path: ' + mediaFile.fullPath);
|
282 | if (callback) callback();
|
283 | }, function (err) {
|
284 | log('Failed to resolve by path: ' + mediaFile.fullPath);
|
285 | log('Error: ' + JSON.stringify(err));
|
286 | if (callback) callback();
|
287 | });
|
288 | }
|
289 |
|
290 | function resolveVideo () {
|
291 | clearStatus();
|
292 | var options = { limit: 1, duration: 5 };
|
293 | navigator.device.capture.captureVideo(function (mediaFiles) {
|
294 | captureVideoWin(mediaFiles);
|
295 | resolveMediaFile(mediaFiles[0], function () {
|
296 | resolveMediaFileURL(mediaFiles[0]);
|
297 | });
|
298 | }, captureVideoFail, options);
|
299 | }
|
300 |
|
301 | function clearStatus () {
|
302 | document.getElementById('camera_status').innerHTML = '';
|
303 | document.getElementById('camera_image').src = 'about:blank';
|
304 | document.getElementById('camera_image2').src = 'about:blank';
|
305 | document.getElementById('camera_image3').src = 'about:blank';
|
306 | }
|
307 |
|
308 |
|
309 |
|
310 | contentEl.innerHTML = '<div id="info" style="white-space: pre-wrap">' +
|
311 | '<b>Status:</b> <div id="camera_status"></div>' +
|
312 | 'img1: <img width="100" id="camera_image">' +
|
313 | 'img2: <img width="100" id="camera_image2">' +
|
314 | 'img3: <img width="100" id="camera_image3">' +
|
315 | 'video: <div id="video_container"></div>' +
|
316 | '</div><div id="audio"></div>' +
|
317 | 'Expected result: Audio recorder will come up. Press record button to record for 10 seconds. Press Done. Status box will update with audio file and automatically play recording.' +
|
318 | '<p/> <div id="image"></div>' +
|
319 | 'Expected result: Status box will update with image just taken.' +
|
320 | '<p/> <div id="images"></div>' +
|
321 | 'Expected result: Status box will update with images just taken.' +
|
322 | '<p/> <div id="video"></div>' +
|
323 | 'Expected result: Record 10 second video. Status box will update with video file that you can play.' +
|
324 | '<p/> <div id="video_and_resolve"></div>' +
|
325 | 'Expected result: Record 5 second video. Status box will show that URL was resolved and video will get added at the bottom of the status box for playback.' +
|
326 | '<p/> <div id="prohibited_camera_video"></div>' +
|
327 | 'Expected result (iOS only): camera picker and alert with message that camera access is prohibited are shown. The alert has 2 buttons: OK and Settings. By click on "OK" camera is hidden, by pressing Settings it shows privacy settings for the app' +
|
328 | '<p/> <div id="prohibited_camera_image"></div>' +
|
329 | 'Expected result (iOS only): camera picker and alert with message that camera access is prohibited are shown. The alert has 2 buttons: OK and Settings. By click on "OK" camera is hidden, by pressing Settings it shows privacy settings for the app';
|
330 |
|
331 | createActionButton('Capture 10 sec of audio and play', function () {
|
332 | getAudio();
|
333 | }, 'audio');
|
334 |
|
335 | createActionButton('Capture 1 image', function () {
|
336 | getImage();
|
337 | }, 'image');
|
338 |
|
339 | createActionButton('Capture 3 images', function () {
|
340 | getImages();
|
341 | }, 'images');
|
342 |
|
343 | createActionButton('Capture 10 sec of video', function () {
|
344 | getVideo();
|
345 | }, 'video');
|
346 |
|
347 | createActionButton('Capture 5 sec of video and resolve', function () {
|
348 | resolveVideo();
|
349 | }, 'video_and_resolve');
|
350 |
|
351 | createActionButton('Disable access to Camera and click to capture video', function () {
|
352 | getVideoPermissionError();
|
353 | }, 'prohibited_camera_video');
|
354 |
|
355 | createActionButton('Disable access to Camera and click to capture image', function () {
|
356 | getImagePermissionError();
|
357 | }, 'prohibited_camera_image');
|
358 | };
|