如何使用 Espresso-web 断言元素 属性 值?

How to assert element property value with Espresso-web?

我正在开发默认 Android WebView 的子类,顶部有一些附加功能(内容过滤)。所以我覆盖 shouldInterceptRequest(...) 并阻止加载某些资源(假设文件名为“image.png”的图像)。

现在我想在 Espresso-Web 的帮助下测试这个功能。所以我确实启动了嵌入式 http 服务器(使用 WireMock)并加载了一些使用该“image.png”的网页,预计会被阻止。

如何断言 ID 为“someId”的 DOM 元素的状态?

我希望有这样的东西:

    onWebView().
        .withElement(findElement(Locator.ID, blockImageId)) // finds the DOM node
        .check(webMatches(getProperty("naturalWidth"), equalTo("0"))) // "getProperty"?

我需要的是像“getProperty()”这样的东西,它只是生成 JS 来访问 findElement(Locator.ID, blockImageId) 找到的节点的 属性,有没有什么不对的-盒子?

我找到了 getText(),但它似乎以完全不同的方式找到了它(所以我不能只请求另一个“节点 属性”):

/** Returns the visible text beneath a given DOM element. */
  public static Atom<String> getText() {
    return new GetTextTransformingAtom(new GetVisibleTextSimpleAtom(), castOrDie(String.class));
  }

我可以用 JS 的方式做到:


      // JS-way helpers
    
      const val naturalWidth = "naturalWidth"
      const val notBlockedImageWidth = 50
      const val blockedImageWidth = 0

      fun getPropertyForElementId(elementId: String, property: String): Atom<String> =
          Atoms.script(
              """return String(document.getElementById("$elementId").$property);""",
              Atoms.castOrDie(String::class.java))

      fun imageIsBlocked(elementId: String): WebAssertion<String>? = WebViewAssertions.webMatches(
          getPropertyForElementId(elementId, naturalWidth),
          equalTo(blockedImageWidth.toString())) {
          """An image with id="$elementId" IS expected to be blocked, but it's NOT."""
      }

      // part of the test

      val redImage = "image.png"
      load(
            listOf(blockingPathPrefix),
            """
            |<html>
            |<body>
            |  <img id="$blockImageId" src="${blockingPathPrefix}$redImage"/>
            |  <img id="$notBlockImageId" src="$greenImage"/>
            |</body>
            |</html>
            |""".trimMargin()
        )

        onWebView()
            .withTimeout(1, TimeUnit.SECONDS)  // it's already loaded
            .check(imageIsBlocked(blockImageId))       // red image IS blocked
            .check(imageIsNotBlocked(notBlockImageId)) // green image is NOT blocked

我确实知道我这样做的方式不是最理想的,因为它连接了所有内容:搜索节点并立即访问,我想知道什么是正确的方法。有什么建议、链接吗?

PS。 “naturalWidth”只是一个 属性 在这种特殊情况下对我有帮助。在通常情况下,我只需要访问找到的 DOM 节点的 属性,下次它可以是其他 属性(例如“style.display”以检查元素可见性)。

PS。任何人都可以解释如何写 WebDriverAtomScripts,例如。类似于 WebDriverAtomScripts.GET_VISIBLE_TEXT_ANDROID?

is there anything out-of-box?

你的问题的答案是“否”,我认为没有什么比像你正在做的那样创建 Atom 更好的开箱即用(或类似的方法 Atoms.scriptWithArgs 或子类 SimpleAtom).

最好的办法是在此处提交功能请求(然后可能 propose/contribute 实施):https://github.com/android/android-test

您可以使用 xpath 在 html 文档上断言,但这不适用于您正在寻找的计算 DOM 节点属性。

onWebView()
.check(webContent(hasElementWithXpath("//*[@id=\"myButton\" and @type=\"button\"]")))