Appium React Native未准备好进行文本输入



我最近切换到Appium+webdriverIO进行E2E测试。除了一个与文本输入相关的测试用例外,一切都运行得很好。

基本上,测试中的组件是一个使用redux表单进行表单管理的登录屏幕。我经常收到错误"'"login-field" Other' is not ready for a text input. Neither the accessibility element itself nor its accessible descendants have the input focus"。组件如下:

SignInScreen.tsx

export class SignInScreen extends React.Component<any> {
render() {
const { handleSubmit, submitting, style } = this.props;
return (
<View style={style}>
<View>
<View>
<Field
name="login"
component={Input}
accessibilityLabel="login-field"
testID="login-field"
/>
<Field
secureTextEntry
name="password"
component={Input}
accessibilityLabel="password-field"
testID="password-field"
/>
</View>
</View>
</View>
);
}
}

Input.tsx

export class Input extends React.Component {
render() {
const {
input,
meta: { error, active, focused },
accessibilityLabel,
testID
} = this.props;
const showError = !active && !!error && !focused;
const errorText = "ERROR!"
return (
<View style={[style, styles.container]}>
<TextInput
autoCapitalize="none"
value={input.value}
onChangeText={input.onChange}
onFocus={input.onFocus}
onBlur={input.onBlur}
accessibilityLabel={accessibilityLabel},
testID={testID}
/>
<View style={{height: 30}}>
{showError && (
<Text>{errorText}</Text>
)}
</View>
</View>
);
}
}

SignInScreen.test.ts

describe('Sign In Screen Test', () => {
let client;
beforeAll(async () => {
// set up code
});
afterAll(async () => {
// tear down code
});
it('Can login', async () => {
const loginField = await client.$('~login-field');
await loginField.setValue('test@gmail.com'); // error here
const passwordField = await client.$('~password-field');
await passwordField.set('password' + 'n');
});
});

我确实意识到,当我在Input.tsx组件中的现有<TextInput />组件上添加一个额外的<TextInput />时,测试用例就会起作用,如下所示:

Input.tsx

export class Input extends React.Component {
render() {
const {
input,
meta: { error, active, focused },
accessibilityLabel,
testID
} = this.props;
const showError = !active && !!error && !focused;
const errorText = "ERROR!"
return (
<View style={[style, styles.container]}>
<TextInput />
<TextInput
autoCapitalize="none"
value={input.value}
onChangeText={input.onChange}
onFocus={input.onFocus}
onBlur={input.onBlur}
accessibilityLabel={accessibilityLabel},
testID={testID}
/>
<View style={{height: 30}}>
{showError && (
<Text>{errorText}</Text>
)}
</View>
</View>
);
}
}

或者我删除View组件中嵌套错误消息的固定高度,如下所示:

Input.tsx

export class Input extends React.Component {
render() {
const {
input,
meta: { error, active, focused },
accessibilityLabel,
testID
} = this.props;
const showError = !active && !!error && !focused;
const errorText = "ERROR!"
return (
<View style={[style, styles.container]}>
<TextInput
autoCapitalize="none"
value={input.value}
onChangeText={input.onChange}
onFocus={input.onFocus}
onBlur={input.onBlur}
accessibilityLabel={accessibilityLabel},
testID={testID}
/>
<View>
{showError && (
<Text>{errorText}</Text>
)}
</View>
</View>
);
}
}

那是什么呢?我真的很困惑是什么导致Appium在没有进行上述调整的情况下无法获得输入焦点。

我相信这是Appium最近的一个错误-https://github.com/appium/java-client/issues/1386

您不应该为ios指定accessibilityLabel为ios和android指定单独的道具,所以请尝试下一个解决方法:

export default function testID(id) {
return Platform.OS === 'android'
? {
accessible        : true,
accessibilityLabel: id,
}
: {
testID: id,
};
}

然后

<TextInput
{...otherProps}
{...testID('some-testID')}
/>

最新更新