2016-07-14 9 views
3

WebViewのインスタンスを取得しようとしていますので、evaluateJavascript()と呼ぶことができます。私は、カスタム照合を書いた後、以下のような静的変数にWebViewを割り当てようとしました :エスプレッソ:WebViewでevaluateJavascript()を呼び出す方法

public static WebView view1; 

public static Matcher<View> isJavascriptEnabled1() { 
    return new BoundedMatcher<View, WebView>(WebView.class) { 
     @Override 
     public void describeTo(Description description) { 
      description.appendText("WebView with JS enabled"); 
     } 
     @Override 
     public boolean matchesSafely(WebView webView) { 
      view1 =webView; 
      return webView.getSettings().getJavaScriptEnabled(); 
     } 
    }; 
} 

そして、私のテストクラスで私が呼ぶ:

CustomMatcher.isJavascriptEnabled1(); 
CustomMatcher.view1.evaluateJavascript("$('.status dl  dd').get(0).innerText.replace('pts.', '').replace(',', '').trim()\"]",new ValueCallback<String>() { 
    @Override 
    public void onReceiveValue(String s) { 
     Log.d("LogName", s); // Prints asd 
    } 

});

私はエラーを取得する:java.lang.NullPointerException: Attempt to invoke virtual method 'void android.webkit.WebView.evaluateJavascript(java.lang.String, android.webkit.ValueCallback)' on a null object reference

答えて

3

あなたは、ビューに一致するようにMatcherを使用していません。 isJavascriptEnabled1()を呼び出すと、カスタムMatcherの新しいインスタンスが作成されるだけなので、機能していません。しかし、例えば。​​は決して実行されないので、CustomMatcher.view1nullです。あなたはMatcherと一緒Espresso.onView()を使用する必要があなたのコードを動作させるために :

// Use onView and the matcher to find a web view with enabled java script 
Espresso.onView(CustomMatcher.isJavascriptEnabled1()); 

// Now CustomMatcher.view1 should not be null (if there is a web view) 
CustomMatcher.view1.evaluateJavascript("$('.status dl  dd').get(0).innerText.replace('pts.', '').replace(',', '').trim()\"]",new ValueCallback<String>() { 
    @Override 
    public void onReceiveValue(String s) { 
     Log.d("LogName", s); // Prints asd 
    } 
}); 

をしかし、まだ正確ではないthatsの。方法evaluateJavascript()は非同期であり、エスプレッソはコールバック(onReceiveValue())の呼び出しを待たない。したがって、テストはonReceive()が呼び出される前に終了する可能性が最も高いでしょう。

WebViewsのテストではEspresso Webもあります。あなたの目標に応じて、それは有用であるかもしれません。エスプレッソウェブはフードの下でもJavaスクリプトを実行します。

エスプレッソウェブを使わずに、というカスタムを書くことをお勧めします。これは一致するWebViewで実行されます。このアクションは、Javaスクリプトを評価するためにWebViewを使用することができます。

/** 
* {@link ViewAction} that evaluates javascript in a {@link WebView}. 
*/ 
public class EvaluateJsAction implements ViewAction, ValueCallback<String> { 

    private static final long TIME_OUT = 5000; 
    private final String mJsString; 
    private final AtomicBoolean mEvaluateFinished = new AtomicBoolean(false); 

    public EvaluateJsAction(final String javaScriptString) { 
     mJsString = javaScriptString; 
    } 

    @Override 
    public Matcher<View> getConstraints() { 
     return isAssignableFrom(WebView.class); 
    } 

    @Override 
    public String getDescription() { 
     return "evaluate '" + mJsString + "' on webview"; 
    } 

    @Override 
    public void perform(UiController uiController, View view) { 
     uiController.loopMainThreadUntilIdle(); 

     final WebView webView = (WebView) view; 
     webView.evaluateJavascript(mJsString, this); 

     final long timeOut = System.currentTimeMillis() + TIME_OUT; 
     while (!mEvaluateFinished.get()) { 
      if (timeOut < System.currentTimeMillis()) { 
       throw new PerformException.Builder() 
         .withActionDescription(this.getDescription()) 
         .withViewDescription(HumanReadables.describe(view)) 
         .withCause(new RuntimeException(String.format(Locale.US, 
           "Evaluating java script did not finish after %d ms of waiting.", TIME_OUT))) 
         .build(); 
      } 
      uiController.loopMainThreadForAtLeast(50); 
     } 
    } 

    @Override 
    public void onReceiveValue(String value) { 
     mEvaluateFinished.set(true); 
    } 
} 

は、このアクションを使用します。

onView(withJavaScriptEnabled()).perform(new EvaluateJsAction(theJavaScriptString)); 
+0

は本当にこの質問に答えるために、あなたの時間、本当にhelpful.Thanksを感謝しています。 –

関連する問題