/* * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * */ /* eslint-env jasmine */ /* global CaptureAudioOptions, CaptureImageOptions, CaptureVideoOptions, CaptureError */ /* global Media, MediaFile, MediaFileData, resolveLocalFileSystemURL */ exports.defineAutoTests = function () { describe('Capture (navigator.device.capture)', function () { it('capture.spec.1 should exist', function () { expect(navigator.device).toBeDefined(); expect(navigator.device.capture).toBeDefined(); }); it('capture.spec.2 should have the correct properties ', function () { expect(navigator.device.capture.supportedAudioModes).toBeDefined(); expect(navigator.device.capture.supportedImageModes).toBeDefined(); expect(navigator.device.capture.supportedVideoModes).toBeDefined(); }); it('capture.spec.3 should contain a captureAudio function', function () { expect(navigator.device.capture.captureAudio).toBeDefined(); expect(typeof navigator.device.capture.captureAudio === 'function').toBe(true); }); it('capture.spec.4 should contain a captureImage function', function () { expect(navigator.device.capture.captureImage).toBeDefined(); expect(typeof navigator.device.capture.captureImage === 'function').toBe(true); }); it('capture.spec.5 should contain a captureVideo function', function () { expect(navigator.device.capture.captureVideo).toBeDefined(); expect(typeof navigator.device.capture.captureVideo === 'function').toBe(true); }); describe('CaptureAudioOptions', function () { it('capture.spec.6 CaptureAudioOptions constructor should exist', function () { var options = new CaptureAudioOptions(); expect(options).toBeDefined(); expect(options.limit).toBeDefined(); expect(options.duration).toBeDefined(); }); }); describe('CaptureImageOptions', function () { it('capture.spec.7 CaptureImageOptions constructor should exist', function () { var options = new CaptureImageOptions(); expect(options).toBeDefined(); expect(options.limit).toBeDefined(); }); }); describe('CaptureVideoOptions', function () { it('capture.spec.8 CaptureVideoOptions constructor should exist', function () { var options = new CaptureVideoOptions(); expect(options).toBeDefined(); expect(options.limit).toBeDefined(); expect(options.duration).toBeDefined(); }); }); describe('CaptureError interface', function () { it('capture.spec.9 CaptureError constants should be defined', function () { expect(CaptureError.CAPTURE_INTERNAL_ERR).toBe(0); expect(CaptureError.CAPTURE_APPLICATION_BUSY).toBe(1); expect(CaptureError.CAPTURE_INVALID_ARGUMENT).toBe(2); expect(CaptureError.CAPTURE_NO_MEDIA_FILES).toBe(3); }); it('capture.spec.10 CaptureError properties should exist', function () { var error = new CaptureError(); expect(error).toBeDefined(); expect(error.code).toBeDefined(); }); }); describe('MediaFileData', function () { it('capture.spec.11 MediaFileData constructor should exist', function () { var fileData = new MediaFileData(); expect(fileData).toBeDefined(); expect(fileData.bitrate).toBeDefined(); expect(fileData.codecs).toBeDefined(); expect(fileData.duration).toBeDefined(); expect(fileData.height).toBeDefined(); expect(fileData.width).toBeDefined(); }); }); describe('MediaFile', function () { it('capture.spec.12 MediaFile constructor should exist', function () { var fileData = new MediaFile(); expect(fileData).toBeDefined(); expect(fileData.name).toBeDefined(); expect(fileData.type).toBeDefined(); expect(fileData.lastModifiedDate).toBeDefined(); expect(fileData.size).toBeDefined(); }); }); }); }; /******************************************************************************/ /******************************************************************************/ /******************************************************************************/ exports.defineManualTests = function (contentEl, createActionButton) { var pageStartTime = +new Date(); function log (value) { document.getElementById('camera_status').textContent += (new Date() - pageStartTime) / 1000 + ': ' + value + '\n'; console.log(value); } function captureAudioWin (mediaFiles) { var path = mediaFiles[0].fullPath; log('Audio captured: ' + path); var m = new Media(path); m.play(); getFileMetadata(mediaFiles[0]); } function captureAudioFail (e) { log('Error getting audio: ' + e.code); } function getAudio () { clearStatus(); var options = { limit: 1, duration: 10 }; navigator.device.capture.captureAudio(captureAudioWin, captureAudioFail, options); } function captureImageWin (mediaFiles) { var path = mediaFiles[0].fullPath; // Necessary since windows doesn't allow file URLs for elements if (cordova.platformId === 'windows' || cordova.platformId === 'windows8' || cordova.platformId === 'browser') { // eslint-disable-line no-undef path = mediaFiles[0].localURL; } log('Image captured: ' + path); document.getElementById('camera_image').src = path; } function captureImagesWin (mediaFiles) { var path = mediaFiles[0].fullPath; // Necessary since windows doesn't allow file URLs for elements if (cordova.platformId === 'windows' || cordova.platformId === 'windows8' || cordova.platformId === 'browser') { // eslint-disable-line no-undef path = mediaFiles[0].localURL; } var path2 = mediaFiles[1].fullPath; // Necessary since windows doesn't allow file URLs for elements if (cordova.platformId === 'windows' || cordova.platformId === 'windows8' || cordova.platformId === 'browser') { // eslint-disable-line no-undef path = mediaFiles[1].localURL; } var path3 = mediaFiles[2].fullPath; // Necessary since windows doesn't allow file URLs for elements if (cordova.platformId === 'windows' || cordova.platformId === 'windows8' || cordova.platformId === 'browser') { // eslint-disable-line no-undef path = mediaFiles[2].localURL; } log('Image captured: ' + path); log('Image captured: ' + path2); log('Image captured: ' + path3); document.getElementById('camera_image').src = path; document.getElementById('camera_image2').src = path2; document.getElementById('camera_image3').src = path3; } function captureImageFail (e) { log('Error getting image: ' + e.code); } function getImage () { clearStatus(); var options = { limit: 1 }; navigator.device.capture.captureImage(captureImageWin, captureImageFail, options); } function getImages () { clearStatus(); var options = { limit: 3 }; navigator.device.capture.captureImage(captureImagesWin, captureImageFail, options); } function captureVideoWin (mediaFiles) { var path = mediaFiles[0].fullPath; log('Video captured: ' + path); // need to inject the video element into the html // doesn't seem to work if you have a pre-existing video element and // add in a source tag var vid = document.createElement('video'); vid.id = 'theVideo'; vid.width = '320'; vid.height = '240'; vid.controls = 'true'; var source_vid = document.createElement('source'); source_vid.id = 'theSource'; source_vid.src = path; vid.appendChild(source_vid); document.getElementById('video_container').appendChild(vid); getFileMetadata(mediaFiles[0]); } function getFileMetadata (mediaFile) { mediaFile.getFormatData(getMetadataWin, getMetadataFail); } function getMetadataWin (metadata) { var strMetadata = 'duration = ' + metadata.duration + '\n' + 'width = ' + metadata.width + '\n' + 'height = ' + metadata.height; log(strMetadata); } function getMetadataFail (e) { log('Error getting metadata: ' + e.code); } function captureVideoFail (e) { log('Error getting video: ' + e.code); } function getVideo () { clearStatus(); var options = { limit: 1, duration: 10 }; navigator.device.capture.captureVideo(captureVideoWin, captureVideoFail, options); } function permissionWasNotAllowed () { log('Media has been captured. Have you forgotten to disallow camera for this app?'); } function catchPermissionError (error) { if (CaptureError.CAPTURE_PERMISSION_DENIED === error.code) { log('Sucess: permission error has been detected!'); } else { log('Error: another error with code: ' + error.code); } } function getVideoPermissionError () { var options = { limit: 1, duration: 10 }; navigator.device.capture.captureVideo(permissionWasNotAllowed, catchPermissionError, options); } function getImagePermissionError () { var options = { limit: 1 }; navigator.device.capture.captureImage(permissionWasNotAllowed, catchPermissionError, options); } function resolveMediaFileURL (mediaFile, callback) { resolveLocalFileSystemURL(mediaFile.localURL, function (entry) { log('Resolved by URL: ' + mediaFile.localURL); if (callback) callback(); }, function (err) { log('Failed to resolve by URL: ' + mediaFile.localURL); log('Error: ' + JSON.stringify(err)); if (callback) callback(); }); } function resolveMediaFile (mediaFile, callback) { resolveLocalFileSystemURL(mediaFile.fullPath, function (entry) { log('Resolved by path: ' + mediaFile.fullPath); if (callback) callback(); }, function (err) { log('Failed to resolve by path: ' + mediaFile.fullPath); log('Error: ' + JSON.stringify(err)); if (callback) callback(); }); } function resolveVideo () { clearStatus(); var options = { limit: 1, duration: 5 }; navigator.device.capture.captureVideo(function (mediaFiles) { captureVideoWin(mediaFiles); resolveMediaFile(mediaFiles[0], function () { resolveMediaFileURL(mediaFiles[0]); }); }, captureVideoFail, options); } function clearStatus () { document.getElementById('camera_status').innerHTML = ''; document.getElementById('camera_image').src = 'about:blank'; document.getElementById('camera_image2').src = 'about:blank'; document.getElementById('camera_image3').src = 'about:blank'; } /******************************************************************************/ contentEl.innerHTML = '
' + 'Status:
' + 'img1: ' + 'img2: ' + 'img3: ' + 'video:
' + '
' + '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.' + '

' + 'Expected result: Status box will update with image just taken.' + '

' + 'Expected result: Status box will update with images just taken.' + '

' + 'Expected result: Record 10 second video. Status box will update with video file that you can play.' + '

' + '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.' + '

' + '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' + '

' + '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'; createActionButton('Capture 10 sec of audio and play', function () { getAudio(); }, 'audio'); createActionButton('Capture 1 image', function () { getImage(); }, 'image'); createActionButton('Capture 3 images', function () { getImages(); }, 'images'); createActionButton('Capture 10 sec of video', function () { getVideo(); }, 'video'); createActionButton('Capture 5 sec of video and resolve', function () { resolveVideo(); }, 'video_and_resolve'); createActionButton('Disable access to Camera and click to capture video', function () { getVideoPermissionError(); }, 'prohibited_camera_video'); createActionButton('Disable access to Camera and click to capture image', function () { getImagePermissionError(); }, 'prohibited_camera_image'); };