diff options
Diffstat (limited to 'tests/DumpRenderTree')
8 files changed, 237 insertions, 120 deletions
diff --git a/tests/DumpRenderTree/assets/run_layout_tests.py b/tests/DumpRenderTree/assets/run_layout_tests.py index b6e7bf3..ceac5d2 100755 --- a/tests/DumpRenderTree/assets/run_layout_tests.py +++ b/tests/DumpRenderTree/assets/run_layout_tests.py @@ -176,7 +176,7 @@ def main(options, args): # Count crashed tests. crashed_tests = [] - timeout_ms = '30000' + timeout_ms = '15000' if options.time_out_ms: timeout_ms = options.time_out_ms diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/CallbackProxy.java b/tests/DumpRenderTree/src/com/android/dumprendertree/CallbackProxy.java index 5780c43..b62db51 100644 --- a/tests/DumpRenderTree/src/com/android/dumprendertree/CallbackProxy.java +++ b/tests/DumpRenderTree/src/com/android/dumprendertree/CallbackProxy.java @@ -74,6 +74,8 @@ public class CallbackProxy extends Handler implements EventSender, LayoutTestCon private static final int LAYOUT_SET_CAN_OPEN_WINDOWS = 42; private static final int SET_GEOLOCATION_PERMISSION = 43; private static final int OVERRIDE_PREFERENCE = 44; + private static final int LAYOUT_DUMP_CHILD_FRAMES_TEXT = 45; + private static final int SET_XSS_AUDITOR_ENABLED = 46; CallbackProxy(EventSender eventSender, LayoutTestController layoutTestController) { @@ -175,7 +177,11 @@ public class CallbackProxy extends Handler implements EventSender, LayoutTestCon break; case LAYOUT_DUMP_TEXT: - mLayoutTestController.dumpAsText(); + mLayoutTestController.dumpAsText(msg.arg1 == 1); + break; + + case LAYOUT_DUMP_CHILD_FRAMES_TEXT: + mLayoutTestController.dumpChildFramesAsText(); break; case LAYOUT_DUMP_HISTORY: @@ -273,6 +279,10 @@ public class CallbackProxy extends Handler implements EventSender, LayoutTestCon boolean value = msg.getData().getBoolean("value"); mLayoutTestController.overridePreference(key, value); break; + + case SET_XSS_AUDITOR_ENABLED: + mLayoutTestController.setXSSAuditorEnabled(msg.arg1 == 1); + break; } } @@ -377,7 +387,15 @@ public class CallbackProxy extends Handler implements EventSender, LayoutTestCon } public void dumpAsText() { - obtainMessage(LAYOUT_DUMP_TEXT).sendToTarget(); + obtainMessage(LAYOUT_DUMP_TEXT, 0).sendToTarget(); + } + + public void dumpAsText(boolean enablePixelTests) { + obtainMessage(LAYOUT_DUMP_TEXT, enablePixelTests ? 1 : 0).sendToTarget(); + } + + public void dumpChildFramesAsText() { + obtainMessage(LAYOUT_DUMP_CHILD_FRAMES_TEXT).sendToTarget(); } public void dumpBackForwardList() { @@ -498,4 +516,8 @@ public class CallbackProxy extends Handler implements EventSender, LayoutTestCon message.getData().putBoolean("value", value); message.sendToTarget(); } + + public void setXSSAuditorEnabled(boolean flag) { + obtainMessage(SET_XSS_AUDITOR_ENABLED, flag ? 1 : 0, 0).sendToTarget(); + } } diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/FileFilter.java b/tests/DumpRenderTree/src/com/android/dumprendertree/FileFilter.java index 77fd3ed..939c623 100644 --- a/tests/DumpRenderTree/src/com/android/dumprendertree/FileFilter.java +++ b/tests/DumpRenderTree/src/com/android/dumprendertree/FileFilter.java @@ -73,43 +73,67 @@ public class FileFilter { static final String[] ignoreTestList = { "editing/selection/move-left-right.html", // Causes DumpRenderTree to hang + "fast/js/excessive-comma-usage.html", // Tests huge initializer list, causes OOM. "fast/js/regexp-charclass-crash.html", // RegExp is too large, causing OOM "fast/regex/test1.html", // Causes DumpRenderTree to hang with V8 "fast/regex/slow.html" // Causes DumpRenderTree to hang with V8 }; static void fillIgnoreResultList() { - // This first block of tests are for HTML5 features, for which Android + // This first block of tests are for features for which Android // should pass all tests. They are skipped only temporarily. // TODO: Fix these failing tests and remove them from this list. + ignoreResultList.add("fast/events/touch/basic-multi-touch-events.html"); // Requires multi-touch + ignoreResultList.add("fast/events/touch/touch-target.html"); // Requires multi-touch ignoreResultList.add("http/tests/appcache/empty-manifest.html"); // flaky + ignoreResultList.add("http/tests/appcache/fallback.html"); // http://b/issue?id=2713004 ignoreResultList.add("http/tests/appcache/foreign-iframe-main.html"); // flaky - skips states ignoreResultList.add("http/tests/appcache/manifest-with-empty-file.html"); // flaky ignoreResultList.add("storage/database-lock-after-reload.html"); // Succeeds but DumpRenderTree does not read result correctly ignoreResultList.add("storage/hash-change-with-xhr.html"); // Succeeds but DumpRenderTree does not read result correctly - - // Will always fail - ignoreResultList.add("dom/svg/level3/xpath"); // XPath not supported + ignoreResultList.add("storage/open-database-creation-callback-isolated-world.html"); // Requires layoutTestController.evaluateScriptInIsolatedWorld() + ignoreResultList.add("storage/statement-error-callback-isolated-world.html"); // Requires layoutTestController.evaluateScriptInIsolatedWorld() + ignoreResultList.add("storage/statement-success-callback-isolated-world.html"); // Requires layoutTestController.evaluateScriptInIsolatedWorld() + ignoreResultList.add("storage/transaction-callback-isolated-world.html"); // Requires layoutTestController.evaluateScriptInIsolatedWorld() + ignoreResultList.add("storage/transaction-error-callback-isolated-world.html"); // Requires layoutTestController.evaluateScriptInIsolatedWorld() + ignoreResultList.add("storage/transaction-success-callback-isolated-world.html"); // Requires layoutTestController.evaluateScriptInIsolatedWorld() + + // Expected failures due to unsupported features. + ignoreResultList.add("fast/events/touch/touch-coords-in-zoom-and-scroll.html"); // Requires eventSender.zoomPageIn(),zoomPageOut() ignoreResultList.add("fast/workers"); // workers not supported - ignoreResultList.add("fast/xpath"); // XPath not supported ignoreResultList.add("http/tests/eventsource/workers"); // workers not supported ignoreResultList.add("http/tests/workers"); // workers not supported ignoreResultList.add("http/tests/xmlhttprequest/workers"); // workers not supported ignoreResultList.add("storage/domstorage/localstorage/private-browsing-affects-storage.html"); // private browsing not supported ignoreResultList.add("storage/domstorage/sessionstorage/private-browsing-affects-storage.html"); // private browsing not supported + ignoreResultList.add("storage/indexeddb"); // indexeddb not supported ignoreResultList.add("storage/private-browsing-readonly.html"); // private browsing not supported ignoreResultList.add("websocket/tests/workers"); // workers not supported + // Expected failures due to missing expected results + ignoreResultList.add("dom/xhtml/level3/core/canonicalform08.xhtml"); + ignoreResultList.add("dom/xhtml/level3/core/canonicalform09.xhtml"); + ignoreResultList.add("dom/xhtml/level3/core/documentgetinputencoding03.xhtml"); + ignoreResultList.add("dom/xhtml/level3/core/entitygetinputencoding02.xhtml"); + ignoreResultList.add("dom/xhtml/level3/core/entitygetxmlversion02.xhtml"); + ignoreResultList.add("dom/xhtml/level3/core/nodegetbaseuri05.xhtml"); + ignoreResultList.add("dom/xhtml/level3/core/nodegetbaseuri07.xhtml"); + ignoreResultList.add("dom/xhtml/level3/core/nodegetbaseuri09.xhtml"); + ignoreResultList.add("dom/xhtml/level3/core/nodegetbaseuri10.xhtml"); + ignoreResultList.add("dom/xhtml/level3/core/nodegetbaseuri11.xhtml"); + ignoreResultList.add("dom/xhtml/level3/core/nodegetbaseuri15.xhtml"); + ignoreResultList.add("dom/xhtml/level3/core/nodegetbaseuri17.xhtml"); + ignoreResultList.add("dom/xhtml/level3/core/nodegetbaseuri18.xhtml"); + ignoreResultList.add("dom/xhtml/level3/core/nodelookupnamespaceuri01.xhtml"); + ignoreResultList.add("dom/xhtml/level3/core/nodelookupprefix19.xhtml"); + // TODO: These need to be triaged ignoreResultList.add("fast/css/case-transform.html"); // will not fix #619707 ignoreResultList.add("fast/dom/Element/offsetLeft-offsetTop-body-quirk.html"); // different screen size result in extra spaces in Apple compared to us ignoreResultList.add("fast/dom/Window/Plug-ins.html"); // need test plugin - ignoreResultList.add("fast/dom/Window/window-properties.html"); // xslt and xpath elements missing from property list ignoreResultList.add("fast/dom/Window/window-screen-properties.html"); // pixel depth ignoreResultList.add("fast/dom/Window/window-xy-properties.html"); // requires eventSender.mouseDown(),mouseUp() ignoreResultList.add("fast/dom/attribute-namespaces-get-set.html"); // http://b/733229 - ignoreResultList.add("fast/dom/gc-9.html"); // requires xpath support - ignoreResultList.add("fast/dom/global-constructors.html"); // requires xslt and xpath support ignoreResultList.add("fast/dom/object-embed-plugin-scripting.html"); // dynamic plugins not supported ignoreResultList.add("fast/dom/tabindex-clamp.html"); // there is extra spacing in the file due to multiple input boxes fitting on one line on Apple, ours are wrapped. Space at line ends are stripped. ignoreResultList.add("fast/events/anchor-image-scrolled-x-y.html"); // requires eventSender.mouseDown(),mouseUp() @@ -172,8 +196,6 @@ public class FileFilter { ignoreResultList.add("fast/replaced/image-map.html"); // requires eventSender.mouseDown(),mouseUp() ignoreResultList.add("fast/text/plain-text-line-breaks.html"); // extra spacing because iFrames rendered next to each other on Apple ignoreResultList.add("profiler"); // profiler is not supported - ignoreResultList.add("svg"); // svg is not supported - } } diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/FsUtils.java b/tests/DumpRenderTree/src/com/android/dumprendertree/FsUtils.java index 6cfce41..5d34e25 100644 --- a/tests/DumpRenderTree/src/com/android/dumprendertree/FsUtils.java +++ b/tests/DumpRenderTree/src/com/android/dumprendertree/FsUtils.java @@ -49,8 +49,13 @@ public class FsUtils { //no creation of instances } - public static void findLayoutTestsRecursively(BufferedOutputStream bos, + /** + * @return the number of tests in the list. + */ + public static int writeLayoutTestListRecursively(BufferedOutputStream bos, String dir, boolean ignoreResultsInDir) throws IOException { + + int testCount = 0; Log.v(LOGTAG, "Searching tests under " + dir); File d = new File(dir); @@ -68,7 +73,7 @@ public class FsUtils { // If this is not a test directory, we don't recurse into it. if (!FileFilter.isNonTestDir(s)) { Log.v(LOGTAG, "Recursing on " + s); - findLayoutTestsRecursively(bos, s, ignoreResultsInDir); + testCount += writeLayoutTestListRecursively(bos, s, ignoreResultsInDir); } continue; } @@ -79,7 +84,9 @@ public class FsUtils { continue; } - if ((s.toLowerCase().endsWith(".html") || s.toLowerCase().endsWith(".xml")) + if ((s.toLowerCase().endsWith(".html") + || s.toLowerCase().endsWith(".xml") + || s.toLowerCase().endsWith(".xhtml")) && !s.endsWith("TEMPLATE.html")) { Log.v(LOGTAG, "Recording " + s); bos.write(s.getBytes()); @@ -88,8 +95,10 @@ public class FsUtils { bos.write((" IGNORE_RESULT").getBytes()); } bos.write('\n'); + testCount++; } } + return testCount; } public static void updateTestStatus(String statusFile, String s) { diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestController.java b/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestController.java index 9236345..15288b5 100644 --- a/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestController.java +++ b/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestController.java @@ -18,29 +18,30 @@ package com.android.dumprendertree; public interface LayoutTestController { - public void dumpAsText(); - public void waitUntilDone(); - public void notifyDone(); - - // Force a redraw of the page - public void display(); - // Used with pixel dumps of content - public void testRepaint(); - - // If the page title changes, add the information to the output. - public void dumpTitleChanges(); - public void dumpBackForwardList(); - public void dumpChildFrameScrollPositions(); - public void dumpEditingCallbacks(); - - // Show/Hide window for window.onBlur() testing - public void setWindowIsKey(boolean b); - // Mac function, used to disable events going to the window - public void setMainFrameIsFirstResponder(boolean b); - - public void dumpSelectionRect(); - - // invalidate and draw one line at a time of the web view. + public void dumpAsText(boolean enablePixelTests); + public void dumpChildFramesAsText(); + public void waitUntilDone(); + public void notifyDone(); + + // Force a redraw of the page + public void display(); + // Used with pixel dumps of content + public void testRepaint(); + + // If the page title changes, add the information to the output. + public void dumpTitleChanges(); + public void dumpBackForwardList(); + public void dumpChildFrameScrollPositions(); + public void dumpEditingCallbacks(); + + // Show/Hide window for window.onBlur() testing + public void setWindowIsKey(boolean b); + // Mac function, used to disable events going to the window + public void setMainFrameIsFirstResponder(boolean b); + + public void dumpSelectionRect(); + + // invalidate and draw one line at a time of the web view. public void repaintSweepHorizontally(); // History testing functions @@ -67,4 +68,7 @@ public interface LayoutTestController { public void setGeolocationPermission(boolean allow); public void overridePreference(String key, boolean value); + + // For XSSAuditor tests + public void setXSSAuditorEnabled(boolean flag); } diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestsAutoTest.java b/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestsAutoTest.java index 9ccf549..132f17a 100644 --- a/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestsAutoTest.java +++ b/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestsAutoTest.java @@ -20,9 +20,7 @@ import com.android.dumprendertree.TestShellActivity.DumpDataType; import com.android.dumprendertree.forwarder.AdbUtils; import com.android.dumprendertree.forwarder.ForwardService; -import android.app.Instrumentation; import android.content.Intent; -import android.os.Bundle; import android.os.Environment; import android.test.ActivityInstrumentationTestCase2; import android.util.Log; @@ -158,18 +156,11 @@ public class LayoutTestsAutoTest extends ActivityInstrumentationTestCase2<TestSh private String mJsEngine; private String mTestPathPrefix; private boolean mFinished; + private int mTestCount; + private int mResumeIndex; public LayoutTestsAutoTest() { - super("com.android.dumprendertree", TestShellActivity.class); - } - - // This function writes the result of the layout test to - // Am status so that it can be picked up from a script. - private void passOrFailCallback(String file, boolean result) { - Instrumentation inst = getInstrumentation(); - Bundle bundle = new Bundle(); - bundle.putBoolean(file, result); - inst.sendStatus(0, bundle); + super(TestShellActivity.class); } private void getTestList() { @@ -190,6 +181,7 @@ public class LayoutTestsAutoTest extends ActivityInstrumentationTestCase2<TestSh } catch (Exception e) { Log.e(LOGTAG, "Error while reading test list : " + e.getMessage()); } + mTestCount = mTestList.size(); } private void resumeTestList() { @@ -200,6 +192,7 @@ public class LayoutTestsAutoTest extends ActivityInstrumentationTestCase2<TestSh if (mTestList.elementAt(i).equals(line)) { mTestList = new Vector<String>(mTestList.subList(i+1, mTestList.size())); mTestListIgnoreResult = new Vector<Boolean>(mTestListIgnoreResult.subList(i+1, mTestListIgnoreResult.size())); + mResumeIndex = i + 1; break; } } @@ -232,14 +225,22 @@ public class LayoutTestsAutoTest extends ActivityInstrumentationTestCase2<TestSh // The generic result is at <path>/<name>-expected.txt // First try the Android-specific result at // platform/android-<js-engine>/<path>/<name>-expected.txt + // then + // platform/android/<path>/<name>-expected.txt int pos = test.lastIndexOf('.'); if (pos == -1) return null; String genericExpectedResult = test.substring(0, pos) + "-expected.txt"; String androidExpectedResultsDir = "platform/android-" + mJsEngine + "/"; - String androidExpectedResult = - genericExpectedResult.replaceFirst(LAYOUT_TESTS_ROOT, LAYOUT_TESTS_ROOT + androidExpectedResultsDir); + String androidExpectedResult = genericExpectedResult.replaceFirst(LAYOUT_TESTS_ROOT, + LAYOUT_TESTS_ROOT + androidExpectedResultsDir); File f = new File(androidExpectedResult); + if (f.exists()) + return androidExpectedResult; + androidExpectedResultsDir = "platform/android/"; + androidExpectedResult = genericExpectedResult.replaceFirst(LAYOUT_TESTS_ROOT, + LAYOUT_TESTS_ROOT + androidExpectedResultsDir); + f = new File(androidExpectedResult); return f.exists() ? androidExpectedResult : genericExpectedResult; } @@ -300,7 +301,7 @@ public class LayoutTestsAutoTest extends ActivityInstrumentationTestCase2<TestSh } } - private void runTestAndWaitUntilDone(TestShellActivity activity, String test, int timeout, boolean ignoreResult) { + private void runTestAndWaitUntilDone(TestShellActivity activity, String test, int timeout, boolean ignoreResult, int testNumber) { activity.setCallback(new TestShellCallback() { public void finished() { synchronized (LayoutTestsAutoTest.this) { @@ -336,6 +337,9 @@ public class LayoutTestsAutoTest extends ActivityInstrumentationTestCase2<TestSh intent.putExtra(TestShellActivity.TEST_URL, FsUtils.getTestUrl(test)); intent.putExtra(TestShellActivity.RESULT_FILE, resultFile); intent.putExtra(TestShellActivity.TIMEOUT_IN_MILLIS, timeout); + intent.putExtra(TestShellActivity.TOTAL_TEST_COUNT, mTestCount); + intent.putExtra(TestShellActivity.CURRENT_TEST_NUMBER, testNumber); + intent.putExtra(TestShellActivity.STOP_ON_REF_ERROR, true); activity.startActivity(intent); // Wait until done. @@ -375,8 +379,8 @@ public class LayoutTestsAutoTest extends ActivityInstrumentationTestCase2<TestSh // Read settings mTestPathPrefix = (new File(LAYOUT_TESTS_ROOT + runner.mTestPath)).getAbsolutePath(); mRebaselineResults = runner.mRebaseline; - // JSC is the default JavaScript engine. - mJsEngine = runner.mJsEngine == null ? "jsc" : runner.mJsEngine; + // V8 is the default JavaScript engine. + mJsEngine = runner.mJsEngine == null ? "v8" : runner.mJsEngine; int timeout = runner.mTimeoutInMillis; if (timeout <= 0) { @@ -393,7 +397,7 @@ public class LayoutTestsAutoTest extends ActivityInstrumentationTestCase2<TestSh resumeTestList(); TestShellActivity activity = getActivity(); - activity.setDefaultDumpDataType(DumpDataType.DUMP_AS_TEXT); + activity.setDefaultDumpDataType(DumpDataType.EXT_REPR); // Run tests. int addr = -1; @@ -410,7 +414,9 @@ public class LayoutTestsAutoTest extends ActivityInstrumentationTestCase2<TestSh boolean ignoreResult = mTestListIgnoreResult.elementAt(i); FsUtils.updateTestStatus(TEST_STATUS_FILE, s); // Run tests - runTestAndWaitUntilDone(activity, s, runner.mTimeoutInMillis, ignoreResult); + // i is 0 based, but test count is 1 based so add 1 to i here. + runTestAndWaitUntilDone(activity, s, runner.mTimeoutInMillis, ignoreResult, + i + 1 + mResumeIndex); } FsUtils.updateTestStatus(TEST_STATUS_FILE, "#DONE"); @@ -435,7 +441,7 @@ public class LayoutTestsAutoTest extends ActivityInstrumentationTestCase2<TestSh try { File tests_list = new File(LAYOUT_TESTS_LIST_FILE); BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(tests_list, false)); - FsUtils.findLayoutTestsRecursively(bos, getTestPath(), false); // Don't ignore results + FsUtils.writeLayoutTestListRecursively(bos, getTestPath(), false); // Don't ignore results bos.flush(); bos.close(); } catch (Exception e) { diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/Menu.java b/tests/DumpRenderTree/src/com/android/dumprendertree/Menu.java index 9c4b572..0b00d65 100644 --- a/tests/DumpRenderTree/src/com/android/dumprendertree/Menu.java +++ b/tests/DumpRenderTree/src/com/android/dumprendertree/Menu.java @@ -53,29 +53,38 @@ public class Menu extends FileList { intent.setClass(this, TestShellActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); intent.putExtra(TestShellActivity.TEST_URL, "file://" + filename); + intent.putExtra(TestShellActivity.TOTAL_TEST_COUNT, 1); + intent.putExtra(TestShellActivity.CURRENT_TEST_NUMBER, 1); startActivity(intent); } @Override void processDirectory(String path, boolean selection) { - generateTestList(path); + int testCount = generateTestList(path); Intent intent = new Intent(Intent.ACTION_VIEW); intent.setClass(this, TestShellActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); intent.putExtra(TestShellActivity.UI_AUTO_TEST, LAYOUT_TESTS_LIST_FILE); + intent.putExtra(TestShellActivity.TOTAL_TEST_COUNT, testCount); + // TestShellActivity will process this intent once and increment the test index + // before running the first test, so pass 0 here to allow for that. + intent.putExtra(TestShellActivity.CURRENT_TEST_NUMBER, 0); startActivity(intent); } - private void generateTestList(String path) { + private int generateTestList(String path) { + int testCount = 0; try { File tests_list = new File(LAYOUT_TESTS_LIST_FILE); BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(tests_list, false)); - FsUtils.findLayoutTestsRecursively(bos, path, false); // Don't ignore results + testCount = FsUtils.writeLayoutTestListRecursively( + bos, path, false); // Don't ignore results bos.flush(); bos.close(); } catch (Exception e) { Log.e(LOGTAG, "Error when creating test list: " + e.getMessage()); } + return testCount; } } diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/TestShellActivity.java b/tests/DumpRenderTree/src/com/android/dumprendertree/TestShellActivity.java index 7475719..f4773b5 100644 --- a/tests/DumpRenderTree/src/com/android/dumprendertree/TestShellActivity.java +++ b/tests/DumpRenderTree/src/com/android/dumprendertree/TestShellActivity.java @@ -35,6 +35,8 @@ import android.os.Handler; import android.os.Message; import android.util.Log; import android.view.ViewGroup; +import android.view.Window; +import android.webkit.ConsoleMessage; import android.webkit.GeolocationPermissions; import android.webkit.HttpAuthHandler; import android.webkit.JsPromptResult; @@ -99,6 +101,8 @@ public class TestShellActivity extends Activity implements LayoutTestController Log.v(LOGTAG, "message sent to WebView to dump text."); switch (mDumpDataType) { case DUMP_AS_TEXT: + callback.arg1 = mDumpTopFrameAsText ? 1 : 0; + callback.arg2 = mDumpChildFramesAsText ? 1 : 0; mWebView.documentAsText(callback); break; case EXT_REPR: @@ -117,6 +121,7 @@ public class TestShellActivity extends Activity implements LayoutTestController @Override protected void onCreate(Bundle icicle) { super.onCreate(icicle); + requestWindowFeature(Window.FEATURE_PROGRESS); LinearLayout contentView = new LinearLayout(this); contentView.setOrientation(LinearLayout.VERTICAL); @@ -159,6 +164,9 @@ public class TestShellActivity extends Activity implements LayoutTestController return; } + mTotalTestCount = intent.getIntExtra(TOTAL_TEST_COUNT, mTotalTestCount); + mCurrentTestNumber = intent.getIntExtra(CURRENT_TEST_NUMBER, mCurrentTestNumber); + mTestUrl = intent.getStringExtra(TEST_URL); if (mTestUrl == null) { mUiAutoTestPath = intent.getStringExtra(UI_AUTO_TEST); @@ -172,6 +180,11 @@ public class TestShellActivity extends Activity implements LayoutTestController mTimeoutInMillis = intent.getIntExtra(TIMEOUT_IN_MILLIS, 0); mGetDrawtime = intent.getBooleanExtra(GET_DRAW_TIME, false); mSaveImagePath = intent.getStringExtra(SAVE_IMAGE); + mStopOnRefError = intent.getBooleanExtra(STOP_ON_REF_ERROR, false); + setTitle("Test " + mCurrentTestNumber + " of " + mTotalTestCount); + float ratio = (float)mCurrentTestNumber / mTotalTestCount; + int progress = (int)(ratio * Window.PROGRESS_END); + getWindow().setFeatureInt(Window.FEATURE_PROGRESS, progress); Log.v(LOGTAG, " Loading " + mTestUrl); mWebView.loadUrl(mTestUrl); @@ -237,6 +250,7 @@ public class TestShellActivity extends Activity implements LayoutTestController Intent intent = new Intent(Intent.ACTION_VIEW); intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); intent.putExtra(TestShellActivity.TEST_URL, FsUtils.getTestUrl(url)); + intent.putExtra(TestShellActivity.CURRENT_TEST_NUMBER, ++mCurrentTestNumber); intent.putExtra(TIMEOUT_IN_MILLIS, 10000); executeIntent(intent); } @@ -329,14 +343,29 @@ public class TestShellActivity extends Activity implements LayoutTestController // ....................................... // LayoutTestController Functions - public void dumpAsText() { + public void dumpAsText(boolean enablePixelTests) { + // Added after webkit update to r63859. See trac.webkit.org/changeset/63730. + if (enablePixelTests) { + Log.v(LOGTAG, "dumpAsText(enablePixelTests == true) not implemented on Android!"); + } + mDumpDataType = DumpDataType.DUMP_AS_TEXT; + mDumpTopFrameAsText = true; if (mWebView != null) { String url = mWebView.getUrl(); Log.v(LOGTAG, "dumpAsText called: "+url); } } + public void dumpChildFramesAsText() { + mDumpDataType = DumpDataType.DUMP_AS_TEXT; + mDumpChildFramesAsText = true; + if (mWebView != null) { + String url = mWebView.getUrl(); + Log.v(LOGTAG, "dumpChildFramesAsText called: "+url); + } + } + public void waitUntilDone() { mWaitUntilDone = true; String url = mWebView.getUrl(); @@ -348,7 +377,9 @@ public class TestShellActivity extends Activity implements LayoutTestController Log.v(LOGTAG, "notifyDone called: " + url); if (mWaitUntilDone) { mWaitUntilDone = false; - mChromeClient.onProgressChanged(mWebView, 101); + if (!mRequestedWebKitData && !mTimedOut && !finished()) { + requestWebKitData(); + } } } @@ -473,6 +504,10 @@ public class TestShellActivity extends Activity implements LayoutTestController } } + public void setXSSAuditorEnabled (boolean flag) { + mWebView.getSettings().setXSSAuditorEnabled(flag); + } + private final WebViewClient mViewClient = new WebViewClient(){ @Override public void onPageFinished(WebView view, String url) { @@ -490,11 +525,30 @@ public class TestShellActivity extends Activity implements LayoutTestController drawPageToFile(mSaveImagePath + "/" + name + ".png", mWebView); } } + // Calling finished() will check if we've met all the conditions for completing - // this test and move to the next one if we are ready. + // this test and move to the next one if we are ready. Otherwise we ask WebCore to + // dump the page. if (finished()) { return; } + + if (!mWaitUntilDone && !mRequestedWebKitData && !mTimedOut) { + requestWebKitData(); + } else { + if (mWaitUntilDone) { + Log.v(LOGTAG, "page finished loading but waiting for notifyDone to be called: " + url); + } + + if (mRequestedWebKitData) { + Log.v(LOGTAG, "page finished loading but webkit data has already been requested: " + url); + } + + if (mTimedOut) { + Log.v(LOGTAG, "page finished loading but already timed out: " + url); + } + } + super.onPageFinished(view, url); } @@ -536,44 +590,8 @@ public class TestShellActivity extends Activity implements LayoutTestController private final WebChromeClient mChromeClient = new WebChromeClient() { @Override - public void onProgressChanged(WebView view, int newProgress) { - - // notifyDone calls this with 101%. We only want to update this flag if this - // is the real call from WebCore. - if (newProgress == 100) { - mOneHundredPercentComplete = true; - } - - // With the flag updated, we can now proceed as normal whether the progress update came from - // WebCore or notifyDone. - if (newProgress >= 100) { - // finished() will check if we are ready to move to the next test and do so if we are. - if (finished()) { - return; - } - - if (!mTimedOut && !mWaitUntilDone && !mRequestedWebKitData) { - String url = mWebView.getUrl(); - Log.v(LOGTAG, "Finished: "+ url); - requestWebKitData(); - } else { - String url = mWebView.getUrl(); - if (mTimedOut) { - Log.v(LOGTAG, "Timed out before finishing: " + url); - } else if (mWaitUntilDone) { - Log.v(LOGTAG, "Waiting for notifyDone: " + url); - } else if (mRequestedWebKitData) { - Log.v(LOGTAG, "Requested webkit data ready: " + url); - } - } - } - } - - @Override public void onReceivedTitle(WebView view, String title) { - if (title.length() > 30) - title = "..."+title.substring(title.length()-30); - setTitle(title); + setTitle("Test " + mCurrentTestNumber + " of " + mTotalTestCount + ": "+ title); if (mDumpTitleChanges) { mTitleChanges.append("TITLE CHANGED: "); mTitleChanges.append(title); @@ -676,15 +694,28 @@ public class TestShellActivity extends Activity implements LayoutTestController } @Override - public void onConsoleMessage(String message, int lineNumber, - String sourceID) { + public boolean onConsoleMessage(ConsoleMessage consoleMessage) { + String msg = "CONSOLE MESSAGE: line " + consoleMessage.lineNumber() + ": " + + consoleMessage.message() + "\n"; if (mConsoleMessages == null) { mConsoleMessages = new StringBuffer(); } - String consoleMessage = "CONSOLE MESSAGE: line " - + lineNumber +": "+ message +"\n"; - mConsoleMessages.append(consoleMessage); - Log.v(LOGTAG, "LOG: "+consoleMessage); + mConsoleMessages.append(msg); + Log.v(LOGTAG, "LOG: " + msg); + // the rationale here is that if there's an error of either type, and the test was + // waiting for "notifyDone" signal to finish, then there's no point in waiting + // anymore because the JS execution is already terminated at this point and a + // "notifyDone" will never come out so it's just wasting time till timeout kicks in + if ((msg.contains("Uncaught ReferenceError:") || msg.contains("Uncaught TypeError:")) + && mWaitUntilDone && mStopOnRefError) { + Log.w(LOGTAG, "Terminating test case on uncaught ReferenceError or TypeError."); + mHandler.postDelayed(new Runnable() { + public void run() { + notifyDone(); + } + }, 500); + } + return true; } @Override @@ -730,6 +761,8 @@ public class TestShellActivity extends Activity implements LayoutTestController private void resetTestStatus() { mWaitUntilDone = false; mDumpDataType = mDefaultDumpDataType; + mDumpTopFrameAsText = false; + mDumpChildFramesAsText = false; mTimedOut = false; mDumpTitleChanges = false; mRequestedWebKitData = false; @@ -739,10 +772,10 @@ public class TestShellActivity extends Activity implements LayoutTestController mEventSender.clearTouchPoints(); mEventSender.clearTouchMetaState(); mPageFinished = false; - mOneHundredPercentComplete = false; mDumpWebKitData = false; mGetDrawtime = false; mSaveImagePath = null; + setDefaultWebSettings(mWebView); } private long[] getDrawWebViewTime(WebView view, int count) { @@ -779,7 +812,7 @@ public class TestShellActivity extends Activity implements LayoutTestController } private boolean canMoveToNextTest() { - return (mDumpWebKitData && mOneHundredPercentComplete && mPageFinished && !mWaitUntilDone) || mTimedOut; + return (mDumpWebKitData && mPageFinished && !mWaitUntilDone) || mTimedOut; } private void setupWebViewForLayoutTests(WebView webview, CallbackProxy callbackProxy) { @@ -787,6 +820,19 @@ public class TestShellActivity extends Activity implements LayoutTestController return; } + setDefaultWebSettings(webview); + + webview.setWebChromeClient(mChromeClient); + webview.setWebViewClient(mViewClient); + // Setting a touch interval of -1 effectively disables the optimisation in WebView + // that stops repeated touch events flooding WebCore. The Event Sender only sends a + // single event rather than a stream of events (like what would generally happen in + // a real use of touch events in a WebView) and so if the WebView drops the event, + // the test will fail as the test expects one callback for every touch it synthesizes. + webview.setTouchInterval(-1); + } + + public void setDefaultWebSettings(WebView webview) { WebSettings settings = webview.getSettings(); settings.setAppCacheEnabled(true); settings.setAppCachePath(getApplicationContext().getCacheDir().getPath()); @@ -799,15 +845,7 @@ public class TestShellActivity extends Activity implements LayoutTestController settings.setDatabasePath(getDir("databases",0).getAbsolutePath()); settings.setDomStorageEnabled(true); settings.setWorkersEnabled(false); - - webview.setWebChromeClient(mChromeClient); - webview.setWebViewClient(mViewClient); - // Setting a touch interval of -1 effectively disables the optimisation in WebView - // that stops repeated touch events flooding WebCore. The Event Sender only sends a - // single event rather than a stream of events (like what would generally happen in - // a real use of touch events in a WebView) and so if the WebView drops the event, - // the test will fail as the test expects one callback for every touch it synthesizes. - webview.setTouchInterval(-1); + settings.setXSSAuditorEnabled(false); } private WebView mWebView; @@ -824,6 +862,9 @@ public class TestShellActivity extends Activity implements LayoutTestController private String mSaveImagePath; private BufferedReader mTestListReader; private boolean mGetDrawtime; + private int mTotalTestCount; + private int mCurrentTestNumber; + private boolean mStopOnRefError; // States private boolean mTimedOut; @@ -833,6 +874,8 @@ public class TestShellActivity extends Activity implements LayoutTestController // Layout test controller variables. private DumpDataType mDumpDataType; private DumpDataType mDefaultDumpDataType = DumpDataType.EXT_REPR; + private boolean mDumpTopFrameAsText; + private boolean mDumpChildFramesAsText; private boolean mWaitUntilDone; private boolean mDumpTitleChanges; private StringBuffer mTitleChanges; @@ -846,7 +889,6 @@ public class TestShellActivity extends Activity implements LayoutTestController private boolean mPageFinished = false; private boolean mDumpWebKitData = false; - private boolean mOneHundredPercentComplete = false; static final String TIMEOUT_STR = "**Test timeout"; @@ -861,6 +903,9 @@ public class TestShellActivity extends Activity implements LayoutTestController static final String UI_AUTO_TEST = "UiAutoTest"; static final String GET_DRAW_TIME = "GetDrawTime"; static final String SAVE_IMAGE = "SaveImage"; + static final String TOTAL_TEST_COUNT = "TestCount"; + static final String CURRENT_TEST_NUMBER = "TestNumber"; + static final String STOP_ON_REF_ERROR = "StopOnReferenceError"; static final int DRAW_RUNS = 5; static final String DRAW_TIME_LOG = Environment.getExternalStorageDirectory() + |