Revision: 5506
Author: [email protected]
Date: Wed Jul 24 17:33:08 2013
Log: rerefactor browser test driver
https://codereview.appspot.com/11790043
Chrome testing is still failing randomly due to some chromedriver
issue where it hangs forever waiting for something.
This is a refactor that tries to avoid the problem, by reinstating
code to use fresh windows in the same browser instance, but rewritten
a little more cleanly. I've been using this to run Chrome tests
continually on my laptop for a while, and it hasn't failed.
I have low confidence this will actually solve the problem, because
my previous attempt at a fix also ran fine in continual testing on
my laptop. But this was easy to do, and it does have a chance of fixing
the problem, so why not try it.
(My current guess about the failure is that it started happening
because of the forced switch to chromedriver2 because of lack of
support for chromedriver1 in the newer versions of chrome, but I'm
having trouble reproducing a failure and/or capturing info from a
failure, so this is a lot of stumbling in the dark.)
R=kpreid2
http://code.google.com/p/google-caja/source/detail?r=5506
Added:
/trunk/tests/com/google/caja/plugin/Echo.java
Modified:
/trunk/tests/com/google/caja/lang/css/CssPropertyPatternsTest.java
/trunk/tests/com/google/caja/plugin/BrowserTestCase.java
/trunk/tests/com/google/caja/plugin/WebDriverHandle.java
/trunk/tests/com/google/caja/util/TestFlag.java
=======================================
--- /dev/null
+++ /trunk/tests/com/google/caja/plugin/Echo.java Wed Jul 24 17:33:08 2013
@@ -0,0 +1,54 @@
+// Copyright (C) 2013 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.caja.plugin;
+
+import java.io.FileDescriptor;
+import java.io.FileOutputStream;
+import java.io.PrintStream;
+
+/**
+ * Convenience functions for diagnostics during tests.
+ *
+ * <p>Caja's ant junit config buries error messages in xml files
+ * that are written when tests are done, and it's annoying to
+ * start a test and find out 10 minutes later that they all failed because
+ * of some browser testing configuration problem.
+ *
+ * <p>So, this is a method that tries to output directly to the
+ * terminal/console (as well as to the usual places), so that when
+ * you start browser tests, you can notice configuration problems early.
+ */
+public class Echo {
+ public static void echo(String s) {
+ // System.err is captured by junit and goes into ant-reports
+ System.err.println(s);
+
+ // FileDescriptor.err is captured by ant and goes to stdout.
+ // We don't close err since that would close FileDescriptor.err
+ @SuppressWarnings("resource")
+ PrintStream err = new PrintStream(
+ new FileOutputStream(FileDescriptor.err), true);
+ err.println(s);
+ }
+
+ public static void echo(Exception e) {
+ echo(e.toString());
+ }
+
+ public static void rethrow(Exception e) throws Exception {
+ echo(e);
+ throw e;
+ }
+}
=======================================
--- /trunk/tests/com/google/caja/lang/css/CssPropertyPatternsTest.java Mon
Jul 15 14:11:53 2013
+++ /trunk/tests/com/google/caja/lang/css/CssPropertyPatternsTest.java Wed
Jul 24 17:33:08 2013
@@ -33,7 +33,6 @@
import com.google.caja.parser.js.StringLiteral;
import com.google.caja.parser.js.ValueProperty;
import com.google.caja.util.CajaTestCase;
-import com.google.caja.util.FailureIsAnOption;
import com.google.caja.util.Function;
import com.google.caja.util.Lists;
import com.google.caja.util.Name;
=======================================
--- /trunk/tests/com/google/caja/plugin/BrowserTestCase.java Wed Jul 10
16:44:43 2013
+++ /trunk/tests/com/google/caja/plugin/BrowserTestCase.java Wed Jul 24
17:33:08 2013
@@ -17,9 +17,6 @@
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
-import java.io.FileDescriptor;
-import java.io.FileOutputStream;
-import java.io.PrintStream;
import java.util.List;
import org.junit.AfterClass;
@@ -51,6 +48,8 @@
public abstract class BrowserTestCase {
// Constructed @BeforeClass to share a single web browser.
private static WebDriverHandle wdh;
+ private static int serverPort;
+ private static String serverHost;
protected String testBuildVersion = null;
@@ -84,6 +83,17 @@
@BeforeClass
public static void setUpClass() throws Exception {
wdh = new WebDriverHandle();
+ serverPort = TestFlag.SERVER_PORT.getInt(0);
+ serverHost = TestFlag.SERVER_HOSTNAME.getString(null);
+ if (serverHost == null) {
+ // If we're testing a remote browser, we need a hostname it can
+ // use to contact the LocalServer instance.
+ if (TestFlag.WEBDRIVER_URL.truthy()) {
+ serverHost = ThisHostName.value();
+ } else {
+ serverHost = "localhost";
+ }
+ }
}
@AfterClass
@@ -102,69 +112,53 @@
testBuildVersion = version;
}
- static protected PrintStream errStream = null;
-
- // The ant junit runner captures System.err. This returns a handle
- // to fd 2 for messages we want to go to the real stderr.
- static protected PrintStream getErr() {
- if (errStream == null) {
- errStream = new PrintStream(
- new FileOutputStream(FileDescriptor.err), true);
+ private void debugHook() throws Exception {
+ if (!TestFlag.DEBUG_BROWSER.truthy()
&& !TestFlag.DEBUG_SERVER.truthy()) {
+ return;
}
- return errStream;
+ serverPort = TestFlag.SERVER_PORT.getInt(8000);
+ localServer.start(serverPort);
+ String url = testUrl("test-index.html");
+ if (TestFlag.DEBUG_BROWSER.truthy()) {
+ wdh.begin().get(url);
+ }
+ Echo.echo("- See " + url);
+ Thread.currentThread().join();
}
- protected String runBrowserTest(
- String label, boolean isKnownFailure, String pageName,
- String... params) throws Exception {
- int serverPort = TestFlag.SERVER_PORT.getInt(0);
+ private String testUrl(String name) {
+ return "http://" + serverHost + ":" + localServer.getPort()
+ + "/ant-testlib/com/google/caja/plugin/" + name;
+ }
- if (TestFlag.DEBUG_BROWSER.truthy() || TestFlag.DEBUG_SERVER.truthy())
{
- pageName = "test-index.html";
- params = null;
- serverPort = TestFlag.SERVER_PORT.getInt(8000);
- }
-
+ protected String runBrowserTest(
+ String label, boolean isKnownFailure, String name, String... params)
+ throws Exception {
+ debugHook();
String result = "";
boolean passed = false;
try {
- try {
- localServer.start(serverPort);
- } catch (Exception e) {
- getErr().println(e);
- throw e;
- }
+ localServer.start(serverPort);
- String localhost = TestFlag.SERVER_HOSTNAME.getString(null);
- if (localhost == null) {
- if (TestFlag.WEBDRIVER_URL.truthy()) {
- localhost = ThisHostName.value();
- } else {
- localhost = "localhost";
- }
- }
- String page = "http://" + localhost + ":" + localServer.getPort()
- + "/ant-testlib/com/google/caja/plugin/" + pageName;
- if (params != null && params.length > 0) {
- page += "?" + Joiner.on("&").join(params);
+ String url = testUrl(name);
+ if (params != null && 0 < params.length) {
+ url += "?" + Joiner.on("&").join(params);
}
- getErr().println("- Try " + page);
+ Echo.echo("- Running " + url);
- if (TestFlag.DEBUG_SERVER.truthy()) {
- Thread.currentThread().join();
- }
- WebDriver driver = wdh.begin();
- driver.get(page);
- if (TestFlag.DEBUG_BROWSER.truthy()) {
- Thread.currentThread().join();
+ try {
+ WebDriver driver = wdh.begin();
+ driver.get(url);
+ result = driveBrowser(driver);
+ passed = true;
+ wdh.captureResults(label);
+ } finally {
+ wdh.end(passed || isKnownFailure);
}
-
- result = driveBrowser(driver);
- passed = true;
+ } catch (Exception e) {
+ Echo.rethrow(e);
} finally {
- wdh.captureResults(label);
localServer.stop();
- wdh.end(passed || isKnownFailure);
}
return result;
}
=======================================
--- /trunk/tests/com/google/caja/plugin/WebDriverHandle.java Tue Jul 16
10:10:19 2013
+++ /trunk/tests/com/google/caja/plugin/WebDriverHandle.java Wed Jul 24
17:33:08 2013
@@ -14,10 +14,8 @@
package com.google.caja.plugin;
-import java.io.FileDescriptor;
import java.io.FileOutputStream;
import java.io.IOException;
-import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
@@ -50,29 +48,40 @@
private RemoteWebDriver driver = null;
private boolean canExecuteScript = true;
private boolean reportedVersion = false;
+ private String firstWindow = null;
+ private int windowSeq = 0;
+ private boolean windowOpened = false;
// Don't keep more than this many failed test windows. (Otherwise
// a broken tree can overload a machine with browser windows.)
private static final int MAX_FAILS_KEPT = 9;
- private static int fails_kept = 0;
+ private static int failsKept = 0;
WebDriver begin() {
if (driver == null) {
driver = makeDriver();
+ firstWindow = driver.getWindowHandle();
reportVersion(driver);
try {
driver.manage().timeouts().pageLoadTimeout(15, TimeUnit.SECONDS);
} catch (WebDriverException e) {
- log("failed to set pageLoadTimeout: " + e.toString());
+ Echo.echo("failed to set pageLoadTimeout: " + e);
// harmless, ignore
}
try {
driver.manage().timeouts().setScriptTimeout(5, TimeUnit.SECONDS);
} catch (WebDriverException e) {
- log("failed to setScriptTimeout: " + e.toString());
+ Echo.echo("failed to setScriptTimeout: " + e);
// harmless, ignore
}
}
+ // Try to open a new window
+ String name = "cajatest" + (windowSeq++);
+ windowOpened = (Boolean) executeScript(
+ "return !!window.open('', '" + name + "');");
+ if (windowOpened) {
+ driver.switchTo().window(name);
+ }
return driver;
}
@@ -83,7 +92,7 @@
return driver.executeScript(script);
} catch (WebDriverException e) {
canExecuteScript = false;
- log("executeScript failed: " + e);
+ Echo.echo("executeScript failed: " + e);
}
}
return null;
@@ -104,32 +113,28 @@
if (build != null && !"".equals(build)) {
version += " build " + build;
}
- log("webdriver: browser " + name + " version " + version);
- }
-
- private void log(String s) {
- // System.err is captured by junit and goes into ant-reports
- System.err.println(s);
-
- // FileDescriptor.err is captured by ant and goes to stdout.
- // We don't close err since that would close FileDescriptor.err
- @SuppressWarnings("resource")
- PrintStream err = new PrintStream(
- new FileOutputStream(FileDescriptor.err), true);
- err.println(s);
+ Echo.echo("webdriver: browser " + name + " version " + version);
}
void end(boolean passed) {
// If a test fails, drop the driver handle without close or quit,
// leaving the browser open, which is helpful for debugging.
if (!passed && !TestFlag.BROWSER_CLOSE.truthy()
- && fails_kept++ < MAX_FAILS_KEPT) {
+ && failsKept++ < MAX_FAILS_KEPT) {
driver = null;
- } else if (TestFlag.BROWSER_REUSE.truthy()) {
- // TODO(felix8a): this occasionally causes chromedriver to hang
- driver.get("about:blank");
} else {
- closeDriver();
+ try {
+ // If we're reusing the same browser, close the current window.
+ if (windowOpened) {
+ driver.close();
+ driver.switchTo().window(firstWindow);
+ } else {
+ driver.get("about:blank");
+ }
+ } catch (Exception e) {
+ Echo.echo("window cleanup failed: " + e);
+ closeDriver();
+ }
}
}
@@ -212,7 +217,7 @@
byte[] bytes = ss.getScreenshotAs(OutputType.BYTES);
saveToFile(dir + name + ".capture.png", bytes);
} catch (WebDriverException e) {
- log("screenshot failed: " + e);
+ Echo.echo("screenshot failed: " + e);
}
}
=======================================
--- /trunk/tests/com/google/caja/util/TestFlag.java Tue Jul 16 10:10:19 2013
+++ /trunk/tests/com/google/caja/util/TestFlag.java Wed Jul 24 17:33:08 2013
@@ -34,8 +34,6 @@
"test.browser"),
BROWSER_CLOSE(
"test.browser.close"),
- BROWSER_REUSE(
- "test.browser.reuse"),
CAPTURE_TO(
"test.capture.to"),
CHROME_ARGS(
--
---
You received this message because you are subscribed to the Google Groups "Google Caja Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.