描述
我需要编写一个e2e测试,在某种程度上它必须在UIImagePickerController中选择一个图像,我尝试使用element(by.type('UIImagePickerController')). tapAtPoint()
而没有使用。我需要一种选择图像的方法。我已经找到了一个道路来进行本地测试。
另外,嘲笑对我来说不是一个选项,因为我使用了一个更高的版本,这是反应者--本地的--重新包装者所需要的。
复制步骤
element(by.type('UIImagePickerController')).tapAtPoint({ x: 50, y: 200 })
解毒,节点,设备,Xcode和macOS版本
设备和详细的排毒日志
没有日志,设备点击正确的位置,但点击没有效果。
发布于 2019-03-13 21:01:09
注意到最初的问题表明,在提出的情况下,模拟不是一种选择,但我在寻找解决方案时多次遇到这个堆栈溢出问题,并想分享我最终为我的情况想出的结果。
我能够通过在我自己的导出中包装e2e来克服react-native-image-picker
测试的限制:
ImagePicker.js
import ImagePicker from 'react-native-image-picker';
export default ImagePicker;
然后创建一个带有自定义扩展(即e2e.js
)的模拟:
ImagePicker.e2e.js
const mockImageData = '/9j/4AAQSkZ...MORE BASE64 DATA OF CUTE KITTENS HERE.../9k=';
export default {
showImagePicker: function showImagePicker(options, callback) {
if (typeof options === 'function') {
callback = options;
}
callback({
data: mockImageData,
});
},
};
最后,配置metro bundler以确定您的自定义扩展的优先级:
项目根/rn-cli.config.js
const defaultSourceExts = require('metro-config/src/defaults/defaults')
.sourceExts;
module.exports = {
resolver: {
sourceExts: process.env.RN_SRC_EXT
? process.env.RN_SRC_EXT.split(',').concat(defaultSourceExts)
: defaultSourceExts,
},
};
然后将RN_SRC_EXT
环境变量设置为自定义扩展运行:
RN_SRC_EXT=e2e.js react-native start
有关更多信息,请参见解毒模拟指南。
发布于 2018-01-12 00:33:26
不确定这是否相关,但对于iOS 11,我甚至无法在Debug层次结构中看到这些原生视图类型。
然而,对于iOS 9和10,我会这样解决问题:
it('select first image from camera roll', async () => {
// select a photo
await element(by.id('select_photo')).tap();
// Choose from Library...
await element(by.traits(['button']).and(by.type('_UIAlertControllerActionView'))).atIndex(1).tap();
// select Cemara Roll, use index 0 for Moments
await element(by.type('UITableViewCellContentView')).atIndex(1).tap();
// select first image
await element(by.type('PUPhotoView')).atIndex(0).tap();
});
使用不同的本机视图类型和可访问性特征,可能还有许多其他解决此问题的可能性。
我只是使用反应-本机图像选择器提供的示例来用上面的代码进行测试:
import React from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View,
PixelRatio,
TouchableOpacity,
Image,
} from 'react-native';
import ImagePicker from 'react-native-image-picker';
export default class App extends React.Component {
state = {
avatarSource: null,
videoSource: null
};
selectPhotoTapped() {
const options = {
quality: 1.0,
maxWidth: 500,
maxHeight: 500,
storageOptions: {
skipBackup: true
}
};
ImagePicker.showImagePicker(options, (response) => {
console.log('Response = ', response);
if (response.didCancel) {
console.log('User cancelled photo picker');
}
else if (response.error) {
console.log('ImagePicker Error: ', response.error);
}
else if (response.customButton) {
console.log('User tapped custom button: ', response.customButton);
}
else {
let source = { uri: response.uri };
// You can also display the image using data:
// let source = { uri: 'data:image/jpeg;base64,' + response.data };
this.setState({
avatarSource: source
});
}
});
}
selectVideoTapped() {
const options = {
title: 'Video Picker',
takePhotoButtonTitle: 'Take Video...',
mediaType: 'video',
videoQuality: 'medium'
};
ImagePicker.showImagePicker(options, (response) => {
console.log('Response = ', response);
if (response.didCancel) {
console.log('User cancelled video picker');
}
else if (response.error) {
console.log('ImagePicker Error: ', response.error);
}
else if (response.customButton) {
console.log('User tapped custom button: ', response.customButton);
}
else {
this.setState({
videoSource: response.uri
});
}
});
}
render() {
return (
<View style={styles.container}>
<TouchableOpacity testID="select_photo" onPress={this.selectPhotoTapped.bind(this)}>
<View style={[styles.avatar, styles.avatarContainer, {marginBottom: 20}]}>
{ this.state.avatarSource === null ? <Text>Select a Photo</Text> :
<Image style={styles.avatar} source={this.state.avatarSource} />
}
</View>
</TouchableOpacity>
<TouchableOpacity onPress={this.selectVideoTapped.bind(this)}>
<View style={[styles.avatar, styles.avatarContainer]}>
<Text>Select a Video</Text>
</View>
</TouchableOpacity>
{ this.state.videoSource &&
<Text style={{margin: 8, textAlign: 'center'}}>{this.state.videoSource}</Text>
}
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF'
},
avatarContainer: {
borderColor: '#9B9B9B',
borderWidth: 1 / PixelRatio.get(),
justifyContent: 'center',
alignItems: 'center'
},
avatar: {
borderRadius: 75,
width: 150,
height: 150
}
});
AppRegistry.registerComponent('example', () => App);
https://stackoverflow.com/questions/48208456
复制相似问题