1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.example.android.permissionrequest.test; 17 18 import android.graphics.Rect; 19 import android.os.SystemClock; 20 import android.test.ActivityInstrumentationTestCase2; 21 import android.view.MotionEvent; 22 import android.view.View; 23 import android.webkit.ConsoleMessage; 24 import android.webkit.WebView; 25 26 import com.example.android.permissionrequest.ConfirmationDialogFragment; 27 import com.example.android.permissionrequest.MainActivity; 28 import com.example.android.permissionrequest.PermissionRequestFragment; 29 import com.example.android.permissionrequest.R; 30 31 import java.util.concurrent.ConcurrentLinkedQueue; 32 33 /** 34 * Tests for PermissionRequest sample. 35 */ 36 public class SampleTests extends ActivityInstrumentationTestCase2<MainActivity> { 37 38 private MainActivity mTestActivity; 39 private PermissionRequestFragment mTestFragment; 40 41 public SampleTests() { 42 super(MainActivity.class); 43 } 44 45 @Override 46 protected void setUp() throws Exception { 47 super.setUp(); 48 mTestActivity = getActivity(); 49 mTestFragment = (PermissionRequestFragment) 50 mTestActivity.getSupportFragmentManager().getFragments().get(1); 51 } 52 53 /** 54 * Test if the test fixture has been set up correctly. 55 */ 56 public void testPreconditions() { 57 assertNotNull("mTestActivity is null", mTestActivity); 58 assertNotNull("mTestFragment is null", mTestFragment); 59 } 60 61 public void testWebView_grantPermissionRequest() throws Throwable { 62 View view = mTestFragment.getView(); 63 assertNotNull(view); 64 final WebView webView = (WebView) view.findViewById(R.id.web_view); 65 assertNotNull(webView); 66 67 final ConsoleMonitor monitor = new ConsoleMonitor(); 68 mTestFragment.setConsoleMonitor(monitor); 69 70 // Click the "Start" button 71 assertTrue(monitor.waitForKeyword("Page loaded", 2000)); 72 clickToggle(webView); 73 74 // Wait for the dialog 75 ConfirmationDialogFragment dialogFragment = waitForDialog(); 76 assertNotNull(dialogFragment); 77 78 // Click "Allow" 79 monitor.reset(); 80 clickDialogButton(dialogFragment, android.R.id.button1); 81 82 assertTrue(monitor.waitForKeyword("Started", 2000)); 83 84 // Click the "Stop" button 85 monitor.reset(); 86 clickToggle(webView); 87 assertTrue(monitor.waitForKeyword("Stopped", 2000)); 88 89 // Click the "Start" button 90 monitor.reset(); 91 clickToggle(webView); 92 93 // Wait for the dialog 94 dialogFragment = waitForDialog(); 95 assertNotNull(dialogFragment); 96 97 // Click "Deny" 98 monitor.reset(); 99 clickDialogButton(dialogFragment, android.R.id.button2); 100 assertTrue(monitor.waitForKeyword("Denied", 2000)); 101 } 102 103 /** 104 * Click the Start/Stop button. 105 * 106 * @param webView The {@link WebView}. 107 * @throws Throwable 108 */ 109 private void clickToggle(final WebView webView) throws Throwable { 110 runTestOnUiThread(new Runnable() { 111 @Override 112 public void run() { 113 Rect rect = new Rect(); 114 webView.getHitRect(rect); 115 int x = rect.width() / 2; 116 int y = 100; 117 MotionEvent event = MotionEvent.obtain(SystemClock.uptimeMillis(), 118 SystemClock.uptimeMillis() + 100, MotionEvent.ACTION_DOWN, x, y, 0); 119 webView.dispatchTouchEvent(event); 120 event = MotionEvent.obtain(SystemClock.uptimeMillis(), 121 SystemClock.uptimeMillis() + 100, MotionEvent.ACTION_UP, x, y, 0); 122 webView.dispatchTouchEvent(event); 123 } 124 }); 125 } 126 127 /** 128 * Wait for the dialog for 2 seconds (100 ms * 20 trials). 129 * 130 * @return The dialog. 131 * @throws InterruptedException 132 */ 133 private ConfirmationDialogFragment waitForDialog() throws InterruptedException { 134 int count = 20; 135 ConfirmationDialogFragment dialog = null; 136 while (0 < count) { 137 dialog = (ConfirmationDialogFragment) mTestFragment.getChildFragmentManager() 138 .findFragmentByTag("dialog"); 139 if (null != dialog) { 140 break; 141 } 142 Thread.sleep(100); 143 --count; 144 } 145 return dialog; 146 } 147 148 /** 149 * Press the specified button on the dialog. 150 * 151 * @param dialogFragment The dialog. 152 * @param buttonId The resource ID of the button to press. 153 * @throws Throwable 154 */ 155 private void clickDialogButton(final ConfirmationDialogFragment dialogFragment, 156 final int buttonId) throws Throwable { 157 runTestOnUiThread(new Runnable() { 158 @Override 159 public void run() { 160 dialogFragment.getDialog().findViewById(buttonId).performClick(); 161 assertFalse(dialogFragment.isVisible()); 162 } 163 }); 164 } 165 166 private class ConsoleMonitor implements PermissionRequestFragment.ConsoleMonitor { 167 168 private final ConcurrentLinkedQueue<String> mMessages = new ConcurrentLinkedQueue<String>(); 169 170 @Override 171 public void onConsoleMessage(ConsoleMessage message) { 172 mMessages.offer(message.message()); 173 } 174 175 public boolean waitForKeyword(String keyword, long timeoutMs) throws InterruptedException { 176 long time = 0; 177 while (time < timeoutMs) { 178 String message; 179 while (null != (message = mMessages.poll())) { 180 if (message.contains(keyword)) { 181 return true; 182 } 183 } 184 Thread.sleep(100); 185 time += 100; 186 } 187 return false; 188 } 189 190 public void reset() { 191 mMessages.clear(); 192 } 193 194 } 195 196 } 197