【问题标题】:FEST: Wait for the GUI to load before doing anythingFEST:在执行任何操作之前等待 GUI 加载
【发布时间】:2012-07-26 17:04:16
【问题描述】:
    @Before public void setUp() {
        Robot robot = BasicRobot.robotWithCurrentAwtHierarchy();
        ApplicationLauncher.application("myApp").start(); 

        Pause.pause(5, TimeUnit.SECONDS); 
        frame = WindowFinder.findFrame("frame0").using(robot);

        JTableFixture table = frame.table(new GenericTypeMatcher<JTable>(JTable.class) {
             @Override protected boolean isMatching(JTable table) {
                return (table instanceof myTreeTable); 
             }  
        });
    }

此代码运行良好。如果我们删除 5 秒的暂停,则找不到该表,因为应用程序需要几秒钟来加载它。

我想知道是否有更清洁的方法。我在 ApplicationLauncher 之后尝试使用 robot.waitForIdle()(我猜一旦 EDT 为空,所有内容都已加载),但它不起作用。

我知道 pause 可以使用某些条件作为何时停止的事件,但我不明白如何编写它,因为 JavaDoc 和官方文档很差。

  • Pause.pause(WaitForComponentToShowCondition.untilIsShowing(frame.component())) :我需要一个组件,如果我通过包装框架它不起作用。而且我不能通过桌子,因为这正是我正在等待得到的。
  • 我明白我可能应该使用 ComponentFoundCondition 但我不明白!我厌倦了:

           ComponentMatcher matcher = new GenericTypeMatcher<JTable>(JTable.class) {
               @Override protected boolean isMatching(JTable table) {
                 return (table instanceof myTreeTable); 
               }  
           };
    
           Pause.pause(new ComponentFoundCondition("DebugMsg", frame.robot.finder(), matcher)); 
    

有什么帮助吗?

【问题讨论】:

    标签: java swing testing robot fest


    【解决方案1】:

    您可以使用ComponentFinder 来定位组件。例如,基于问题中的匹配器:

    final ComponentMatcher matcher = new TypeMatcher(myTreeTable.class);
    
    Pause.pause(new Condition("Waiting for myTreeTable") {
        @Override
        public boolean test() {
            Collection<Component> list = 
                    window.robot.finder().findAll(window.target, matcher);
            return list.size() > 0;
        }
     }, 5000); 
    

    这是一个按名称查找的替代方法:

    final ComponentMatcher nameMatcher = new ComponentMatcher(){
        @Override
        public boolean matches(Component c) {
            return "ComponentName".equals(c.getName()) && c.isShowing();
        }
    };
    
    Pause.pause(new Condition("Waiting") {
        @Override
        public boolean test() {
            Collection<Component> list = 
                    window.robot.finder().findAll(window.target, nameMatcher);
            return list.size() > 0;
        }
     }, 5000);
    

    【讨论】:

    • 奇怪的是,有一个已经存在的用于此目标的 Condition 子类,ComponentFoundCondition。所以你的答案的第一部分应该等于 Pause.pause(new ComponentFoundCondition("Waiting formyTreeTable to load...", frame.robot.finder(), matcher, frame.target), 50000);但似乎条件永远不会满足,你最终会超时
    • 好的,我发现了问题。创建多个事件被认为与没有相同,失败。这意味着如果您确定只有一个 myTreeTable,您可以使用更好的匹配 Pause.pause(new ComponentFoundCondition("Waiting formyTreeTable to load...", frame.robot.finder(), matcher, frame.target), 50000);如果不是,最好像你一样继承 Condition ,并将 size() >0 所以 size()=2 它有效
    • 一个问题:我假设这段代码必须在 EDT 中运行,因为访问组件通常不是线程安全的,对吧?因此,如果我们在测试代码中使用它,我们必须将访问权限包装在 GuiQuery?
    • @nikow 我假设 finder 正在 EDT 上执行其方法。如果这是真的,那么就没有必要包装这些动作。不幸的是,我没有方便的环境来测试这个假设。还有EdtSafeCondition 可能会有所帮助。
    • 是的,这是有道理的,我发现ComponentMatcher 是用@RunsInEDT 注释的。谢谢。
    猜你喜欢
    • 2018-02-07
    • 1970-01-01
    • 2014-05-02
    • 2017-07-18
    • 2020-11-26
    • 2022-06-14
    • 2016-06-16
    • 2012-02-06
    • 2012-02-01
    相关资源
    最近更新 更多