1import Constants from 'expo-constants'; 2import * as ImagePicker from 'expo-image-picker'; 3import { Platform } from 'react-native'; 4 5import * as TestUtils from '../TestUtils'; 6import { isDeviceFarm } from '../utils/Environment'; 7import { alertAndWaitForResponse } from './helpers'; 8 9export const name = 'ImagePicker'; 10 11export async function test({ it, beforeAll, expect, jasmine, describe, afterAll }) { 12 function testMediaObjectShape(shape, type) { 13 expect(shape).toBeDefined(); 14 expect(typeof shape.cancelled).toBe('boolean'); 15 16 if (!shape.cancelled) { 17 expect(typeof shape.uri).toBe('string'); 18 expect(typeof shape.width).toBe('number'); 19 expect(typeof shape.height).toBe('number'); 20 expect(typeof shape.type).toBe('string'); 21 22 expect(shape.uri).not.toBe(''); 23 expect(shape.width).toBeGreaterThan(0); 24 expect(shape.height).toBeGreaterThan(0); 25 26 expect(typeof shape.type).toBe('string'); 27 28 if (type) { 29 expect(shape.type).toBe(type); 30 } 31 32 if (shape.type === 'video') { 33 expect(typeof shape.duration).toBe('number'); 34 expect(shape.duration).toBeGreaterThan(0); 35 } 36 } 37 } 38 39 describe(name, () => { 40 if (isDeviceFarm()) return; 41 42 let originalTimeout; 43 44 beforeAll(async () => { 45 await TestUtils.acceptPermissionsAndRunCommandAsync(() => { 46 return ImagePicker.requestMediaLibraryPermissionsAsync(); 47 }); 48 await TestUtils.acceptPermissionsAndRunCommandAsync(() => { 49 return ImagePicker.requestCameraPermissionsAsync(); 50 }); 51 originalTimeout = jasmine.DEFAULT_TIMEOUT_INTERVAL; 52 jasmine.DEFAULT_TIMEOUT_INTERVAL = originalTimeout * 10; 53 }); 54 55 describe('launchCameraAsync', () => { 56 if (Constants.isDevice) { 57 it('launches the camera', async () => { 58 await alertAndWaitForResponse('Please take a picture for this test to pass.'); 59 const image = await ImagePicker.launchCameraAsync(); 60 expect(image.cancelled).toBe(false); 61 testMediaObjectShape(image); 62 }); 63 64 it('cancels the camera', async () => { 65 await alertAndWaitForResponse('Please cancel the camera for this test to pass.'); 66 const image = await ImagePicker.launchCameraAsync(); 67 expect(image.cancelled).toBe(true); 68 }); 69 } else { 70 it('natively prevents the camera from launching on a simulator', async () => { 71 let err; 72 try { 73 await ImagePicker.launchCameraAsync(); 74 } catch ({ code }) { 75 err = code; 76 } 77 expect(err).toBe('CAMERA_MISSING'); 78 }); 79 } 80 }); 81 82 describe('launchImageLibraryAsync', async () => { 83 it('mediaType: image', async () => { 84 await alertAndWaitForResponse('Please choose an image.'); 85 const image = await ImagePicker.launchImageLibraryAsync({ 86 mediaTypes: ImagePicker.MediaTypeOptions.Images, 87 }); 88 89 testMediaObjectShape(image, 'image'); 90 }); 91 92 it('mediaType: video', async () => { 93 await alertAndWaitForResponse('Please choose a video.'); 94 const video = await ImagePicker.launchImageLibraryAsync({ 95 mediaTypes: ImagePicker.MediaTypeOptions.Videos, 96 }); 97 98 testMediaObjectShape(video, 'video'); 99 }); 100 101 it('allows editing', async () => { 102 await alertAndWaitForResponse('Please choose an image to crop.'); 103 const image = await ImagePicker.launchImageLibraryAsync({ 104 mediaTypes: ImagePicker.MediaTypeOptions.Images, 105 allowsEditing: true, 106 }); 107 108 testMediaObjectShape(image, 'image'); 109 }); 110 111 it('allows editing and returns base64', async () => { 112 await alertAndWaitForResponse('Please choose an image to crop.'); 113 const image = await ImagePicker.launchImageLibraryAsync({ 114 mediaTypes: ImagePicker.MediaTypeOptions.Images, 115 allowsEditing: true, 116 base64: true, 117 }); 118 119 testMediaObjectShape(image, 'image'); 120 if (!image.cancelled) { 121 expect(typeof image.base64).toBe('string'); 122 expect(image.base64).not.toBe(''); 123 expect(image.base64).not.toContain('\n'); 124 expect(image.base64).not.toContain('\r'); 125 } 126 }); 127 128 if (Platform.OS === 'ios' && parseInt(Platform.Version, 10) > 10) { 129 it('videoExportPreset should affect video dimensions', async () => { 130 const video = await ImagePicker.launchImageLibraryAsync({ 131 mediaTypes: ImagePicker.MediaTypeOptions.Videos, 132 videoExportPreset: ImagePicker.VideoExportPreset.H264_640x480, 133 }); 134 135 testMediaObjectShape(video, 'video'); 136 137 if (!video.cancelled) { 138 expect(video.width).toBeLessThanOrEqual(640); 139 expect(video.height).toBeLessThanOrEqual(480); 140 } 141 }); 142 } 143 }); 144 145 afterAll(() => { 146 jasmine.DEFAULT_TIMEOUT_INTERVAL = originalTimeout; 147 }); 148 }); 149} 150