You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

自定义禁用按钮getAttributes()返回enabled属性错误问题排查

Detox getAttributes()返回enabled属性错误问题排查

问题现象

在Android和iOS平台使用Detox的getAttributes()方法时,遇到元素enabled属性返回错误的情况。通过Appium Inspector和Layout Inspector确认,对应testID的元素处于禁用状态,但Detox无法验证这一点,返回的enabled值为true。Appium inspector显示:enabled: false

预期行为

在此场景下,预期getAttributes()返回的enabled属性值为false。

复现代码

自定义按钮BaseButton代码

import React from 'react';
import {Animated, Platform, Pressable} from 'react-native';
import {rippleColors} from './types';

const Wrapper = ({containerStyle, children, testID}) => {
  if (!containerStyle) {
    return <>{children}</>;
  }
  return <Animated.View testID={testID} style={containerStyle}>{children}</Animated.View>;
};

const BaseButton = ({
  variant = 'outline',
  onPress,
  disable,
  testID,
  containerStyle,
  buttonStyle,
  children,
  borderless = false,
  radius,
  foreground,
  ...rest
}) => {
  return (
    <Wrapper containerStyle={containerStyle} testID={testID + '.wrapper'}>
      <Pressable
        testID={testID}
        rippleColor={rippleColors[variant]}
        android_ripple={{
          color: rippleColors[variant],
          borderless,
          radius,
          foreground,
        }}
        onPress={onPress}
        disabled={disable}
        enabled={!disable}
        style={({pressed}) => [
          buttonStyle,
          Platform.OS === 'ios' && {
            backgroundColor: pressed ? rippleColors[variant] : 'transparent',
          },
        ]}
        {...rest}>
        {children}
      </Pressable>
    </Wrapper>
  );
};

export default BaseButton;

按钮在汉堡菜单Header组件中的使用代码

import React, {useCallback} from 'react';
import {StyleSheet, View} from 'react-native';
import useTheme from '@/theme';
import {BaseButton, Body, Icon} from '@/components';
import {Navigation} from 'react-native-navigation';
import {useNavigation} from 'react-native-navigation-hooks';

const styles = theme =>
  StyleSheet.create({
    button: {
      flexDirection: 'row',
      padding: theme.spacing.sizes.l,
      alignItems: 'center',
      justifyContent: 'space-between',
    },
  });

const Header = ({
  title,
  action,
  root,
  setSection,
  disable = false,
  selected = false,
}) => {
  const {theme} = useTheme();
  const style = styles(theme);
  const {mergeOptions} = useNavigation();

  const onPress = useCallback(async () => {
    if (root) {
      await Navigation.setRoot(root);
      return;
    }

    if (action) {
      mergeOptions({sideMenu: {left: {visible: false}}});
      action();
      return;
    }

    setSection && setSection(title);
  }, [action, mergeOptions, root, setSection, title]);

  return (
    <BaseButton
      disable={disable}
      onPress={onPress}
      testID={`common.hamburger.section.${title}`}>
      <View style={style.button}>
        <Body
          testID={`hamburger.menu.header.${title}`}
          variant="m"
          numberOfLines={1}
          tx={`hamburger-menu.header.${title}`}
          color={disable ? theme.colors.basic.t48 : undefined}
        />
        {!action && !root && (
          <>
            {selected && (
              <Icon name="up" size="m" color={theme.colors.darkGrey.base} />
            )}
            {!selected && (
              <Icon
                name="down"
                size="m"
                color={
                  disable ? theme.colors.basic.t24 : theme.colors.darkGrey.base
                }
              />
            )}
          </>
        )}
      </View>
    </BaseButton>
  );
};

export default Header;

运行环境

  • Detox版本:20.28.0
  • React Native版本:0.72.5
  • 未启用Fabric渲染系统
  • Node版本:18.20.4
  • 设备型号:Pixel 7a
  • Android版本:Android 15.0 arm64-v8a
  • 测试框架:jest

Detox日志信息

执行console.log(JSON.stringify(await element(by.id(ElementIds.HamburgerMenu.operationSection)).getAttributes(), null, 2))后,日志显示返回的enabled值为true,导致验证元素禁用状态失败,报错信息如下:

12:25:29.755 detox[9681] [90mi[39m 验证元素状态为"disabled"失败,元素匹配规则为'[{"type":"Invocation","value":{"target":{"type":"Class","value":"com.wix.detox.espresso.DetoxMatcher"},"method":"matcherForAnd","args":[{"type":"Invocation","value":{"target":{"type":"Class","value":"com.wix.detox.espresso.DetoxMatcher"},"method":"matcherForClass","args":["android.view.ViewGroup"]}},{"type":"Invocation","value":{"target":{"type":"Class","value":"com.wix.detox.espresso.DetoxMatcher"},"method":"matcherForTestId","args":["common.hamburger.section.operation",{"type":"boolean","value":false}]}}]}},{"type":"Invocation","value":{"target":{"type":"Class","value":"com.wix.detox.espresso.DetoxMatcher"},"method":"matcherForText","args":["TAŞIMA FAALİYETLERİM",{"type":"boolean","value":false}]}}]': 错误:元素未禁用: [{"type":"Invocation","value":{"target":{"type":"Class","value":"com.wix.detox.espresso.DetoxMatcher"},"method":"matcherForAnd","args":[{"type":"Invocation","value":{"target":{"type":"Class","value":"com.wix.detox.espresso.DetoxMatcher"},"method":"matcherForClass","args":["android.view.ViewGroup"]}},{"type":"Invocation","value":{"target":{"type":"Class","value":"com.wix.detox.espresso.DetoxMatcher"},"method":"matcherForTestId","args":["common.hamburger.section.operation",{"type":"boolean","value":false}]}}]}},{"type":"Invocation","value":{"target":{"type":"Class","value":"com.wix.detox.espresso.DetoxMatcher"},"method":"matcherForText","args":["TAŞIMA FAALİYETLERİM",{"type":"boolean","value":false}]}}]
    在 HamburgerMenu.<anonymous> (/Users/erdem.kilic/Desktop/lastmile-courier-app/e2e/base/BasePage.ts:60:19)
    在 Generator.next (<anonymous>)
    在 asyncGeneratorStep (/Users/erdem.kilic/Desktop/lastmile-courier-app/node_modules/@babel/runtime/helpers/asyncToGenerator.js:3:17)
    在 _next (/Users/erdem.kilic/Desktop/lastmile-courier-app/node_modules/@babel/runtime/helpers/asyncToGenerator.js:17:9)
    在 processTicksAndRejections (node:internal/process/task_queues:95:5)

内容的提问来源于stack exchange,提问作者erdemkiiliic

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 01:17:33