com.gorillalogic.fonemonkey.web.WebViewClientWrapper.java Source code

Java tutorial

Introduction

Here is the source code for com.gorillalogic.fonemonkey.web.WebViewClientWrapper.java

Source

/*  MonkeyTalk - a cross-platform functional testing tool
Copyright (C) 2012 Gorilla Logic, Inc.
    
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
    
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Affero General Public License for more details.
    
You should have received a copy of the GNU Affero General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>. */

package com.gorillalogic.fonemonkey.web;

import java.lang.reflect.Method;

import org.apache.commons.codec.net.URLCodec;

import android.graphics.Bitmap;
import android.net.http.SslError;
import android.os.Message;
import android.view.KeyEvent;
import android.webkit.HttpAuthHandler;
import android.webkit.SslErrorHandler;
import android.webkit.WebView;
import android.webkit.WebViewClient;

import com.gorillalogic.fonemonkey.automators.WebViewAutomator;

/* 
 * Hack alert:
 * WebView.addJavaScriptInterface doesn't work if called after a page has already been loaded.
 * AndroidWebDriver relies on addJavaScriptInterface to bridge between JS and Java.
 * Because we might not find out about a WebView until after its initial page has been loaded,
 * we use this mechanism instead whereby we intercept dummy url requests.
 */
public class WebViewClientWrapper extends WebViewClient {
    private WebViewClient client;

    // private WebViewRecorder recorder;

    public WebViewClientWrapper(WebView view) {
        Method meth;
        try {
            // recorder = new WebViewRecorder(webView);
            // webView.addJavascriptInterface(recorder, "mtrecorder");

            meth = WebView.class.getDeclaredMethod("getWebViewClient", (Class<?>[]) null);
            this.client = (WebViewClient) meth.invoke(view, (Object[]) null);
            if (client == null) {
                client = new WebViewClient();
            }
        } catch (Exception e) {
            throw new IllegalStateException("Error getting WebViewClient: " + e.getMessage(), e);
        }
        view.setWebViewClient(this);
        // view.loadUrl("javascript:window.webdriver = {resultMethod: function(result) {window.location = \"http://mtdummy?monkeytalkresult=\" + result}}");

    }

    @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url) {
        String decoded;
        if (url.contains("mtdummy")) {
            try {
                decoded = new URLCodec().decode(url, "UTF-8");
                // We seem to be double-encoded...
                decoded = new URLCodec().decode(decoded, "UTF-8");
            } catch (Exception e) {
                throw new IllegalStateException(e);
            }
            String[] result = decoded.split("monkeytalkresult=");
            if (result.length == 1) {
                WebViewAutomator.reportResult(null);
                return true;
            }
            if (result.length > 1) {
                WebViewAutomator.reportResult(result[result.length - 1]);
                return true;
            }
        }
        return client.shouldOverrideUrlLoading(view, url);
    }

    public void onTooManyRedirects(WebView view, Message cancelMsg, Message continueMsg) {
        client.onTooManyRedirects(view, cancelMsg, continueMsg);
    }

    public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
        client.onReceivedError(view, errorCode, description, failingUrl);
    }

    public void doUpdateVisitedHistory(WebView view, String url, boolean isReload) {
        client.doUpdateVisitedHistory(view, url, isReload);
    }

    public boolean equals(Object arg0) {
        return client.equals(arg0);
    }

    public int hashCode() {
        return client.hashCode();
    }

    public void onPageStarted(WebView view, String url, Bitmap favicon) {
        client.onPageStarted(view, url, favicon);
        // recorder.setJsAttached(false);
    }

    public void onPageFinished(WebView view, String url) {
        client.onPageFinished(view, url);

        // final String lib = WebViewAutomator.fileToString("monkeytalk.js");
        // String s = "javascript:" + lib;
        // webView.loadUrl(s);

        // webView.loadUrl("javascript:( document.onclick = function (event) { alert('works' + event); } ) ()");
        // probably where we add record logic
        // webView.loadUrl("javascript:( function () { alert('woohoo'); } ) ()");

        WebViewRecorder.attachJs(view);
    }

    public void onLoadResource(WebView view, String url) {
        client.onLoadResource(view, url);

        // final String lib = WebViewAutomator.fileToString("monkeytalk.js");
        // String s = "javascript:" + lib;
        // String s =
        // "javascript:console.log('count: ' + document.getElementsByTagName('*').length);";
        // recorder.webViewDidChange();
    }

    public void onFormResubmission(WebView view, Message dontResend, Message resend) {
        client.onFormResubmission(view, dontResend, resend);
    }

    public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
        client.onReceivedSslError(view, handler, error);
    }

    public void onReceivedHttpAuthRequest(WebView view, HttpAuthHandler handler, String host, String realm) {
        client.onReceivedHttpAuthRequest(view, handler, host, realm);
    }

    public boolean shouldOverrideKeyEvent(WebView view, KeyEvent event) {
        return client.shouldOverrideKeyEvent(view, event);
    }

    public void onUnhandledKeyEvent(WebView view, KeyEvent event) {
        client.onUnhandledKeyEvent(view, event);
    }

    public void onScaleChanged(WebView view, float oldScale, float newScale) {
        client.onScaleChanged(view, oldScale, newScale);
    }

    public String toString() {
        return client.toString();
    }

}