1 // Copyright 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 package org.chromium.content_public.browser.test.util; 6 7 import org.chromium.base.test.util.CallbackHelper; 8 import org.chromium.content_public.browser.JavaScriptCallback; 9 import org.chromium.content_public.browser.WebContents; 10 11 import java.util.ArrayList; 12 import java.util.Collections; 13 import java.util.List; 14 import java.util.concurrent.TimeUnit; 15 import java.util.concurrent.TimeoutException; 16 17 /** 18 * This class is used to provide callback hooks for tests and related classes. 19 */ 20 public class TestCallbackHelperContainer { 21 private TestWebContentsObserver mTestWebContentsObserver; 22 TestCallbackHelperContainer(final WebContents webContents)23 public TestCallbackHelperContainer(final WebContents webContents) { 24 // TODO(yfriedman): Change callers to be executed on the UI thread. Unfortunately this is 25 // super convenient as the caller is nearly always on the test thread which is fine to block 26 // and it's cumbersome to keep bouncing to the UI thread. 27 TestThreadUtils.runOnUiThreadBlocking( 28 () -> { mTestWebContentsObserver = new TestWebContentsObserver(webContents); }); 29 } 30 31 /** 32 * CallbackHelper for OnPageCommitVisible. 33 */ 34 public static class OnPageCommitVisibleHelper extends CallbackHelper { 35 private String mUrl; notifyCalled(String url)36 public void notifyCalled(String url) { 37 mUrl = url; 38 notifyCalled(); 39 } getUrl()40 public String getUrl() { 41 assert getCallCount() > 0; 42 return mUrl; 43 } 44 } 45 46 /** 47 * CallbackHelper for OnPageFinished. 48 */ 49 public static class OnPageFinishedHelper extends CallbackHelper { 50 private List<String> mUrlList = Collections.synchronizedList(new ArrayList<>()); 51 private String mUrl; notifyCalled(String url)52 public void notifyCalled(String url) { 53 mUrl = url; 54 mUrlList.add(url); 55 notifyCalled(); 56 } getUrl()57 public String getUrl() { 58 assert getCallCount() > 0; 59 return mUrl; 60 } getUrlList()61 public List<String> getUrlList() { 62 return mUrlList; 63 } 64 } 65 66 /** 67 * CallbackHelper for OnPageStarted. 68 */ 69 public static class OnPageStartedHelper extends CallbackHelper { 70 private String mUrl; notifyCalled(String url)71 public void notifyCalled(String url) { 72 mUrl = url; 73 notifyCalled(); 74 } getUrl()75 public String getUrl() { 76 assert getCallCount() > 0; 77 return mUrl; 78 } 79 } 80 81 /** 82 * CallbackHelper for OnReceivedError. 83 */ 84 public static class OnReceivedErrorHelper extends CallbackHelper { 85 private int mErrorCode; 86 private String mDescription; 87 private String mFailingUrl; notifyCalled(int errorCode, String description, String failingUrl)88 public void notifyCalled(int errorCode, String description, String failingUrl) { 89 mErrorCode = errorCode; 90 mDescription = description; 91 mFailingUrl = failingUrl; 92 notifyCalled(); 93 } getErrorCode()94 public int getErrorCode() { 95 assert getCallCount() > 0; 96 return mErrorCode; 97 } getDescription()98 public String getDescription() { 99 assert getCallCount() > 0; 100 return mDescription; 101 } getFailingUrl()102 public String getFailingUrl() { 103 assert getCallCount() > 0; 104 return mFailingUrl; 105 } 106 } 107 108 /** 109 * CallbackHelper for OnEvaluateJavaScriptResult. 110 * This class wraps the evaluation of JavaScript code allowing test code to 111 * synchronously evaluate JavaScript and then test the result. 112 */ 113 public static class OnEvaluateJavaScriptResultHelper extends CallbackHelper { 114 private String mJsonResult; 115 116 /** 117 * Starts evaluation of a given JavaScript code on a given webContents. 118 * @param webContents A WebContents instance to be used. 119 * @param code A JavaScript code to be evaluated. 120 */ evaluateJavaScriptForTests(WebContents webContents, String code)121 public void evaluateJavaScriptForTests(WebContents webContents, String code) { 122 JavaScriptCallback callback = new JavaScriptCallback() { 123 @Override 124 public void handleJavaScriptResult(String jsonResult) { 125 notifyCalled(jsonResult); 126 } 127 }; 128 mJsonResult = null; 129 TestThreadUtils.runOnUiThreadBlocking( 130 () -> webContents.evaluateJavaScriptForTests(code, callback)); 131 } 132 133 /** 134 * Returns true if the evaluation started by evaluateJavaScriptForTests() has completed. 135 */ hasValue()136 public boolean hasValue() { 137 return mJsonResult != null; 138 } 139 140 /** 141 * Returns the JSON result of a previously completed JavaScript evaluation and 142 * resets the helper to accept new evaluations. 143 * @return String JSON result of a previously completed JavaScript evaluation. 144 */ getJsonResultAndClear()145 public String getJsonResultAndClear() { 146 assert hasValue(); 147 String result = mJsonResult; 148 mJsonResult = null; 149 return result; 150 } 151 152 /** 153 * Waits till the JavaScript evaluation finishes and returns true if a value was returned, 154 * false if it timed-out. 155 */ waitUntilHasValue(long timeout, TimeUnit unit)156 public boolean waitUntilHasValue(long timeout, TimeUnit unit) throws TimeoutException { 157 int count = getCallCount(); 158 // Reads and writes are atomic for reference variables in java, this is thread safe 159 if (hasValue()) return true; 160 waitForCallback(count, 1, timeout, unit); 161 return hasValue(); 162 } 163 waitUntilHasValue()164 public boolean waitUntilHasValue() throws TimeoutException { 165 return waitUntilHasValue(CallbackHelper.WAIT_TIMEOUT_SECONDS, TimeUnit.SECONDS); 166 } 167 notifyCalled(String jsonResult)168 public void notifyCalled(String jsonResult) { 169 assert !hasValue(); 170 mJsonResult = jsonResult; 171 notifyCalled(); 172 } 173 } 174 getOnPageStartedHelper()175 public OnPageStartedHelper getOnPageStartedHelper() { 176 return mTestWebContentsObserver.getOnPageStartedHelper(); 177 } 178 getOnPageFinishedHelper()179 public OnPageFinishedHelper getOnPageFinishedHelper() { 180 return mTestWebContentsObserver.getOnPageFinishedHelper(); 181 } 182 getOnReceivedErrorHelper()183 public OnReceivedErrorHelper getOnReceivedErrorHelper() { 184 return mTestWebContentsObserver.getOnReceivedErrorHelper(); 185 } 186 getOnFirstVisuallyNonEmptyPaintHelper()187 public CallbackHelper getOnFirstVisuallyNonEmptyPaintHelper() { 188 return mTestWebContentsObserver.getOnFirstVisuallyNonEmptyPaintHelper(); 189 } 190 } 191