【问题标题】:IBM-RFT: finding _really_ visible objects within a windowIBM-RFT:在窗口中找到_really_可见的对象
【发布时间】:2014-07-18 14:03:53
【问题描述】:

我对 IBM-RFT(8.5 版)有疑问。我正在为使用大量选项卡和面板的相对复杂的应用程序制作自动化测试框架。问题是我无法检查使用 find 方法找到的对象是否现在实际上在屏幕上可见(在前面/最上面其他)。换句话说,我需要一个算法,它只会搜索当前活动(带到前面)的标签。

我已经使用 Delphi 完成了一个非常简单的应用程序来调试这个问题:一个包含 2 个选项卡和每个选项卡上的单个文本字段 (TEdit) 的 TPageControl。主窗口是一个映射对象,所以这是我进行搜索的方式:

TestObject[] objs = window().find(atDescendant(".class", "TEdit"));

如果应用程序刚刚启动(只有第一个文本字段可见 - 第一个选项卡处于活动状态),则 find 方法将返回一个仅包含一个文本字段的数组。但是,如果我激活第二个选项卡,那么(无论我之后做什么)RFT 都会找到这两个文本字段,并且无法区分其中哪一个实际上在屏幕上。

我一直在使用多种自动化工具,但 RFT 中的这件事让我很沮丧。这里有一些更多信息以避免明显的建议。相信我,我一直在寻找答案。

  1. 当我在选项卡之间切换时,所有字段的属性(在对象检查器中可用)都不会改变。 .enabled.visible 等标准属性始终为 true。没错,因为它们只是控件的属性,而不是一些实时的东西。
  2. RFT 对象的方法 isShowing() 始终为两个字段返回 true
  3. RFT 对象的方法 ensureObjectIsVisible() 始终为两个字段返回 true,并且从不切换选项卡以将所需字段带入视图。
  4. 我可以为不可见的字段调用 click()hover() 或任何用户模拟操作,并且测试继续运行,没有任何异常。更重要的是 - 如果在点击时窗口不在焦点上,它确实获得了焦点 - 看起来 RFT 只是将点击发送到不可见对象矩形中心的窗口。
  5. 方法 getClippedScreenRectangle()getScreenRectangle()getVisibleArea() 为不可见的文本字段返回相同的矩形(窗口完全测试期间在屏幕边框内)。
  6. 当我使用 getImage() 生成不可见文本字段的屏幕截图时,这会导致将窗口图像的一部分保存在不可见元素的屏幕矩形内。
  7. 如果我为两个文本字段创建映射对象,唯一的区别是,在这种情况下,刚刚启动的应用程序测试运行将在每次调用 invisible-and-not-yet-even-once- 期间挂起几秒钟激活的文本字段(例如,如果您在应用程序启动后调用 text2().exists(),此时活动选项卡是第一个,它将挂起并最终返回 true )。
  8. 这种不正确的行为和无法区分活动和非活动控件在我调试 Delphi 构建的应用程序和用 Java 编写的实际 SUT 上是相同的。

在我的调试应用程序中,我可以检查父对象以了解哪个文本字段属于哪个选项卡,但我如何找到激活了哪些选项卡?

QTP 和 TestComplete 都具有确保所需对象实际上在屏幕上的功能,如果您尝试单击视图外的对象,两者都会引发异常。更进一步 - QTP 允许访问对象的本机属性和方法,当没有任何 正确 方法来做这件事时,这通常会有所帮助(我可以在我的调试应用程序中检查 ActivePageIndex 以了解哪个选项卡处于活动状态)。

我是不是搞错了什么?还是我读的东西不够仔细?或者这个问题可能是我机器的本地问题?

如何使用 IBM-RFT 检查实际对象的可见性?

【问题讨论】:

    标签: java rft


    【解决方案1】:

    最终我找到了解决方法。出于某种原因,与您实际可以看到的内容一起运行的唯一方法是 getChildAtPoint()。我见过一种使用这种方法的解决方案,但它是关于 HTML 自动化的,在我的情况下不起作用。

    此方法在指定点查找第一个直接子节点。我的想法是从下到上遍历父对象树,并检查每次 getChildAtPoint() 是否为前一个元素的屏幕点返回前一个元素。当容器实际不可见时,返回结果为null。前两种方法可能不是必需的,但由于自动化框架通常是一种魔法黑盒(RFT 绝对是杰出的例子之一),所以让它成为一种保险。

    public boolean isReallySameId(GuiTestObject obj1, GuiTestObject obj2)
    {
        Object id1 = obj1.getProperty(".associatedId");
        Object id2 = obj2.getProperty(".associatedId");
        // I don't know if this property always exists
        if ((id1 == null) || (id2 == null)) return false;
        return (id1.equals(id2));
    }
    
    public boolean isReallyInScreen(GuiTestObject obj)
    {
        Rectangle screen = RootTestObject.getRootTestObject().getScreen().getScreenRectangle();
        Rectangle intersection = screen.intersection(obj.getScreenRectangle());
        return ((intersection.width > 0) && (intersection.height > 0));
    }
    
    public boolean isReallyVisible(GuiTestObject obj)
    {
        if (!isReallyInScreen(obj)) return false; // basic check
        GuiTestObject parent = (GuiTestObject) obj.getMappableParent();
        if (parent == null) return true; // top object in screen
        GuiTestObject found;
        while (parent != null)
        {
            found = (GuiTestObject) parent.getChildAtPoint(obj.getScreenPoint());
            if ((found == null) || (!isReallySameId(found, obj))) return false;
            obj = parent;
            parent = (GuiTestObject) obj.getMappableParent();
        }
        return true;
    }
    

    啊,多么好的挑战啊。谢谢你,RFT! :)

    附:我不确定这个解决方案是否适用于所有类型的测试对象。我特别不确定它是否适用于不可映射的对象。这是我在特定情况下需要的解决方案,因此如果您遇到同样的问题,您可能需要对其进行自定义。

    【讨论】:

      【解决方案2】:

      要确定对象是否可见,您可以尝试这样的方法,看看是否能解决您的问题

      boolean  isActuallyVisible(TestObject t)
          {
              boolean isVisible = true;
              Rectangle r = (Rectangle) t.getProperty(".bounds");
              if(r.width == 0 && r.height ==0)
              {
                  isVisible = false; // bound says height /width is zero , most likely  invisible object.
              }
      
              return isVisible;
          }
      

      【讨论】:

      • PropertyNotFoundException。我已经在某处读过有关此属性的信息,但它根本不存在。
      【解决方案3】:

      我认为最好/唯一的方法是找到一些有区别的属性——无论是文本字段还是父标签。您可以尝试插入属性验证点以查看比对象检查器中更多的属性。或使用getProperties() 并打印所有可用属性:

      Hashtable props = someElement().getProperties();
      Set entries = props.entrySet();
      for (Object entry : entries)
          System.out.println(entry);
      

      【讨论】:

      • 对象的属性列表包含我在对象检查器中看到的相同的 27 个属性(用于文本字段)。创建一个验证点也只允许验证这 27 个道具。正如我之前所说,当我在选项卡之间切换时,这些属性都不会改变。
      • 当您获得父对象(选项卡)时,它们是否对所有属性也具有相同的值,并且没有一个可以区分它们(没有一个可以让您决定哪个是活动的)?
      • 好吧,标签在添加验证点时还有 1 个附加属性 - 它是它们的背景颜色。这几乎没有用:)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多