Search code examples
androidcordovaseleniumcordova-3appium

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


After upgrading to Cordova 3.6.3 from Cordova 3.4.0; my Appium tests cannot go on because of a strange error. The error can be reproed very easily by creating a basic web-view based app on Android which issues a window.location.reload() after a while that the test starts.

Assessing problem

I could assess that the problem is one particular file: cordova.js which becomes part of the js files in my app when I build it with Cordova. My app loads only one javascript file: cordova.js, I removed all other dependencies to other js files. When that file is in my app (even though index.html does not use any function defined in there), my tests fails. If I remove the dependencies to that file, tests go ok!

The problem is that when my app issues a window.location.reload(); my test fail with this error message:

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"}

How to repro

I created a sample app to repro this thing. You can find the app (APK file) and the C# test I used.

The APK to repro this is in attachments. It is possible to run a simple Appium test to repro the problem:

[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);

}

Important

The fact that a dialog is reported is actually very strange. After inspecting a lot I could verify that no native/webview dialog is being shown on my app. In fact I cannot see any dialog and if I try to dismiss this ghost dialog using Appium and WebDriver APIs, the command fail as no dialog can be found.

Notes

Consider that the problem is not in the APIs I use in my test (C# dotnet driver for Appium). Everything happens on my Appium server running on a Mac.


Solution

  • I think this is due to the following prompt-based js<->java communication logic which is run every page reload

    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 native layer can handle this via 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)) so no actual dialog is showed. But Selenium driver looks like can't correctly treat this case.