UNPKG

15.2 kBJavaScriptView Raw
1/*
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20*/
21
22/* eslint-env jasmine */
23/* global CaptureAudioOptions, CaptureImageOptions, CaptureVideoOptions, CaptureError */
24/* global Media, MediaFile, MediaFileData, resolveLocalFileSystemURL */
25
26exports.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
124exports.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 // Necessary since windows doesn't allow file URLs for <img> elements
153 if (cordova.platformId === 'windows' || cordova.platformId === 'windows8' || cordova.platformId === 'browser') { // eslint-disable-line no-undef
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 // Necessary since windows doesn't allow file URLs for <img> elements
163 if (cordova.platformId === 'windows' || cordova.platformId === 'windows8' || cordova.platformId === 'browser') { // eslint-disable-line no-undef
164 path = mediaFiles[0].localURL;
165 }
166 var path2 = mediaFiles[1].fullPath;
167 // Necessary since windows doesn't allow file URLs for <img> elements
168 if (cordova.platformId === 'windows' || cordova.platformId === 'windows8' || cordova.platformId === 'browser') { // eslint-disable-line no-undef
169 path = mediaFiles[1].localURL;
170 }
171 var path3 = mediaFiles[2].fullPath;
172 // Necessary since windows doesn't allow file URLs for <img> elements
173 if (cordova.platformId === 'windows' || cordova.platformId === 'windows8' || cordova.platformId === 'browser') { // eslint-disable-line no-undef
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 // need to inject the video element into the html
205 // doesn't seem to work if you have a pre-existing video element and
206 // add in a source tag
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};