1 // Copyright 2015 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.webview_shell; 6 7 import android.os.Environment; 8 import android.test.ActivityInstrumentationTestCase2; 9 import android.util.Log; 10 11 import java.io.BufferedReader; 12 import java.io.File; 13 import java.io.FileInputStream; 14 import java.io.FileNotFoundException; 15 import java.io.FileOutputStream; 16 import java.io.IOException; 17 import java.io.InputStreamReader; 18 import java.util.concurrent.TimeUnit; 19 import java.util.concurrent.TimeoutException; 20 21 /** 22 * Tests running end-to-end layout tests. 23 */ 24 public class WebViewLayoutTest 25 extends ActivityInstrumentationTestCase2<WebViewLayoutTestActivity> { 26 27 private static final String TAG = "WebViewLayoutTest"; 28 29 private static final String EXTERNAL_PREFIX = 30 Environment.getExternalStorageDirectory().getAbsolutePath() + "/"; 31 private static final String BASE_WEBVIEW_TEST_PATH = "android_webview/tools/WebViewShell/test/"; 32 private static final String BASE_BLINK_TEST_PATH = "third_party/WebKit/LayoutTests/"; 33 private static final String PATH_WEBVIEW_PREFIX = EXTERNAL_PREFIX + BASE_WEBVIEW_TEST_PATH; 34 private static final String PATH_BLINK_PREFIX = EXTERNAL_PREFIX + BASE_BLINK_TEST_PATH; 35 36 private static final long TIMEOUT_SECONDS = 20; 37 38 private WebViewLayoutTestActivity mTestActivity; 39 WebViewLayoutTest()40 public WebViewLayoutTest() { 41 super(WebViewLayoutTestActivity.class); 42 } 43 44 @Override setUp()45 protected void setUp() throws Exception { 46 super.setUp(); 47 mTestActivity = (WebViewLayoutTestActivity) getActivity(); 48 } 49 50 @Override tearDown()51 protected void tearDown() throws Exception { 52 mTestActivity.finish(); 53 super.tearDown(); 54 } 55 56 @Override getInstrumentation()57 public WebViewLayoutTestRunner getInstrumentation() { 58 return (WebViewLayoutTestRunner) super.getInstrumentation(); 59 } 60 testSimple()61 public void testSimple() throws Exception { 62 runWebViewLayoutTest("experimental/basic-logging.html", 63 "experimental/basic-logging-expected.txt"); 64 } 65 testGlobalInterface()66 public void testGlobalInterface() throws Exception { 67 runBlinkLayoutTest("webexposed/global-interface-listing.html", 68 "webexposed/global-interface-listing-expected.txt"); 69 } 70 71 // test helper methods 72 runWebViewLayoutTest(final String fileName, final String fileNameExpected)73 private void runWebViewLayoutTest(final String fileName, final String fileNameExpected) 74 throws Exception { 75 runTest(PATH_WEBVIEW_PREFIX + fileName, PATH_WEBVIEW_PREFIX + fileNameExpected); 76 } 77 runBlinkLayoutTest(final String fileName, final String fileNameExpected)78 private void runBlinkLayoutTest(final String fileName, final String fileNameExpected) 79 throws Exception { 80 ensureJsTestCopied(); 81 runTest(PATH_BLINK_PREFIX + fileName, PATH_WEBVIEW_PREFIX + fileNameExpected); 82 } 83 runTest(final String fileName, final String fileNameExpected)84 private void runTest(final String fileName, final String fileNameExpected) 85 throws FileNotFoundException, IOException, InterruptedException, TimeoutException { 86 loadUrlWebViewAsync("file://" + fileName, mTestActivity); 87 88 if (getInstrumentation().isRebaseline()) { 89 // this is the rebaseline process 90 mTestActivity.waitForFinish(TIMEOUT_SECONDS, TimeUnit.SECONDS); 91 String result = mTestActivity.getTestResult(); 92 writeFile(fileNameExpected, result, true); 93 Log.i(TAG, "file: " + fileNameExpected + " --> rebaselined, length=" + result.length()); 94 } else { 95 String expected = readFile(fileNameExpected); 96 mTestActivity.waitForFinish(TIMEOUT_SECONDS, TimeUnit.SECONDS); 97 String result = mTestActivity.getTestResult(); 98 assertEquals(expected, result); 99 } 100 } 101 loadUrlWebViewAsync(final String fileUrl, final WebViewLayoutTestActivity activity)102 private void loadUrlWebViewAsync(final String fileUrl, 103 final WebViewLayoutTestActivity activity) { 104 getInstrumentation().runOnMainSync(new Runnable() { 105 @Override 106 public void run() { 107 activity.loadUrl(fileUrl); 108 } 109 }); 110 } 111 ensureJsTestCopied()112 private static void ensureJsTestCopied() throws IOException { 113 File jsTestFile = new File(PATH_BLINK_PREFIX + "resources/js-test.js"); 114 if (jsTestFile.exists()) return; 115 String original = readFile(PATH_WEBVIEW_PREFIX + "resources/js-test.js"); 116 writeFile(PATH_BLINK_PREFIX + "resources/js-test.js", original, false); 117 } 118 119 /** 120 * Reads a file and returns it's contents as string. 121 */ readFile(String fileName)122 private static String readFile(String fileName) throws IOException { 123 FileInputStream inputStream = new FileInputStream(new File(fileName)); 124 try { 125 BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); 126 try { 127 StringBuilder contents = new StringBuilder(); 128 String line; 129 130 while ((line = reader.readLine()) != null) { 131 contents.append(line); 132 contents.append("\n"); 133 } 134 return contents.toString(); 135 } finally { 136 reader.close(); 137 } 138 } finally { 139 inputStream.close(); 140 } 141 } 142 143 /** 144 * Writes a file with the given fileName and contents. If overwrite is true overwrites any 145 * exisiting file with the same file name. If the file does not exist any intermediate 146 * required directories are created. 147 */ writeFile(final String fileName, final String contents, boolean overwrite)148 private static void writeFile(final String fileName, final String contents, boolean overwrite) 149 throws FileNotFoundException, IOException { 150 File fileOut = new File(fileName); 151 152 if (fileOut.exists() && !overwrite) { 153 return; 154 } 155 156 String absolutePath = fileOut.getAbsolutePath(); 157 File filePath = new File(absolutePath.substring(0, absolutePath.lastIndexOf("/"))); 158 159 if (!filePath.exists()) { 160 if (!filePath.mkdirs()) 161 throw new IOException("failed to create directories: " + filePath); 162 } 163 164 FileOutputStream outputStream = new FileOutputStream(fileOut); 165 try { 166 outputStream.write(contents.getBytes()); 167 } finally { 168 outputStream.close(); 169 } 170 } 171 } 172