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

Serenity-BDD如何实现隐藏元素的点击与交互操作

问题背景

自定义Screenplay模式下的Performable任务实现测试逻辑时,被上层遮挡的隐藏元素阻碍操作,需要测试角色(Actor)依次完成以下动作:

  1. 点击目标<input>日期输入框
  2. 向输入框传入指定日期字符串
  3. 触发<RETURN>回车键完成输入

原有实现代码如下:

public class Set {
    public static Performable dateFrom(String date) {
        return Task.where("{0} set 'dateFrom' filter to " + date,
            Click.on(SearchPage.dateTimePicker_from),
            Enter.theValue(date).into(SearchPage.dateTimePicker_from)
            .thenHit(RETURN)
        );
    }
}

运行测试抛出明确错误:[main] ERROR - Expected enabled element was not enabled
排查确认根因:目标<input>元素为隐藏状态,存在一个<div>元素遮挡在输入框上层,需要在不修改前端代码的前提下,在自定义Task中完成对该隐藏元素的交互操作。

解决方案

Serenity Screenplay 内置的Click、Enter等交互默认模拟真实用户行为,会强制校验元素可见、可点击、未被遮挡,遇到上述遮罩层+隐藏input的场景,不用改前端代码,按优先级选以下两种实现即可:

  • 方案一(优先选择,完全匹配真实用户操作路径)
    绝大多数日期选择组件的上层div本身就是交互触发区——用户点击div才会激活输入框、弹出日期面板。你只需要在Page对象里补充这个遮挡div的定位,先点这个触发元素,等input变为可交互状态后再执行输入、回车操作即可,示例代码:
public class Set {
    public static Performable dateFrom(String date) {
        return Task.where("{0} set 'dateFrom' filter to " + date,
            // 点击上层遮挡的触发div,激活日期输入框
            Click.on(SearchPage.dateTimePicker_from_trigger),
            Enter.theValue(date).into(SearchPage.dateTimePicker_from)
                    .thenHit(RETURN)
        );
    }
}
  • 方案二(方案一不生效时使用,绕过可见性校验)
    如果组件的input本身是永久隐藏(比如设置了opacity:0、display:none,用户交互全靠上层div代理),可以直接通过JS执行DOM操作,完全绕过Serenity和Selenium的元素可交互性校验,示例代码:
import net.serenitybdd.screenplay.actions.ExecuteJS;
import static org.openqa.selenium.Keys.RETURN;

public class Set {
    public static Performable dateFrom(String date) {
        return Task.where("{0} set 'dateFrom' filter to " + date,
            // JS触发元素点击事件
            ExecuteJS.on(SearchPage.dateTimePicker_from).execute("arguments[0].click()"),
            // JS直接给input赋值
            ExecuteJS.on(SearchPage.dateTimePicker_from).execute("arguments[0].value = arguments[1]", date),
            // JS派发回车键事件,触发组件的回车监听逻辑
            ExecuteJS.on(SearchPage.dateTimePicker_from)
                    .execute("arguments[0].dispatchEvent(new KeyboardEvent('keydown', {key:'Enter', keyCode:13, bubbles:true}))")
        );
    }
}

注意:JS操作不会触发用户真实交互时的所有事件冒泡逻辑,部分组件的输入校验、值同步逻辑是绑定在input、change等原生事件上的,用JS赋值后建议加一步值校验,确认输入内容确实被组件识别、后续查询逻辑能正常触发。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 15:24:34