迁移到 Cordova 3.6.3 后,不存在的对话框会阻止 Android 上的 Appium 测试

Non existing dialog blocks Appium tests on Android after migrating to Cordova 3.6.3

从 Cordova 3.4.0 升级到 Cordova 3.6.3 后;由于一个奇怪的错误,我的 Appium 测试无法继续。通过在 Android 上创建一个基于 Web 视图的基本应用程序,可以很容易地重现该错误,该应用程序会在测试开始一段时间后发出 window.location.reload()

评估问题

我可以判断问题出在一个特定文件:cordova.js 当我使用 Cordova 构建它时,它成为我应用程序中 js 文件的一部分。我的应用程序只加载一个 javascript 文件:cordova.js,我删除了对其他 js 文件的所有其他依赖项。当该文件在我的应用程序中时(即使 index.html 不使用其中定义的任何函数),我的测试失败。如果我删除对该文件的依赖项,测试就可以了!

问题是当我的应用发出 window.location.reload();我的测试失败并显示此错误消息:

info: [debug] Responding to client with error: {"status":26,"value":{"message":"A modal dialog was open, blocking this operation","origValue":"unexpected alert open\n (Session info: webview=)\n (Driver info: chromedriver=2.10.267521,platform=Windows NT 6.3 x86_64)"},"sessionId":"965ba51e54f682559e5b8378095bc3d4"}

如何复制

我创建了一个示例应用程序来重现这个东西。你可以找到我用的app (APK file) and the C# test

重现此内容的 APK 在附件中。可以 运行 一个简单的 Appium 测试来重现问题:

[Test]
public void SimpleTest()
{
    this.appPackage = "com.myorg.myapp";
    this.appActivity = "myapp";
    BeforeAll();
    Thread.Sleep(3000);

    var submitAddressButton = driver.FindElementByClassName("testClass");
    submitAddressButton.Click();

    Thread.Sleep(3000);
    submitAddressButton = driver.FindElementByClassName("testClass");
    Expect(submitAddressButton, Is.Not.Null);

}

重要

报个对话框其实很奇怪。经过大量检查后,我可以确认我的应用程序上没有显示 native/webview 对话框。事实上,我看不到任何对话框,如果我尝试使用 Appium 和 WebDriver API 关闭这个幽灵对话框,命令会失败,因为找不到对话框。

备注

请考虑问题不在我在测试中使用的 API(Appium 的 C# dotnet 驱动程序)。一切都发生在我的 Appium 服务器 运行ning 上 Mac.

我认为这是由于以下基于提示的 js<->java 通信逻辑,即 运行 每个页面重新加载

androidExec.init = function() {
    bridgeSecret = +prompt('', 'gap_init:' + nativeToJsBridgeMode);
    channel.onNativeReady.fire();
}

https://github.com/apache/cordova-android/blob/master/framework/assets/www/cordova.js#L948

Android 本机层可以通过 onJSPrompt (http://developer.android.com/reference/android/webkit/WebChromeClient.html#onJsPrompt(android.webkit.WebView, java.lang.String, java.lang.String, java.lang.String, android.webkit.JsPromptResult)) 来处理这个问题,所以没有显示实际的对话框。但是 Selenium 驱动程序看起来无法正确处理这种情况。