首页 > 解决方案 > 如何使用 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,例如。smth类似于WebDriverAtomScripts.GET_VISIBLE_TEXT_ANDROID

标签: javascriptandroidwebdriverandroid-espressoandroid-espresso-web

解决方案


有什么开箱即用的吗?

Atom你的问题的答案是“不”,我认为没有什么比创建一个你正在做的事情更好的开箱即用(或类似的方法,如Atoms.scriptWithArgsor subclassing SimpleAtom)。

您最好的选择是在此处提交功能请求(然后可能提出/贡献一个实现):https ://github.com/android/android-test

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

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

推荐阅读