Finally, I have an automated test that exercises DynaFaces and jMaki.
If you don't know what those two things are, check out
<http://developers.sun.com/web/swdp/>.
Anyhow, it was a real pain to keep these two things working together
as
jMaki rapidly evolved. Now at least we can have an automated test to
catch regressions.
SECTION: Changes
A dist/mcp-test/src/main/java/jsf_jmaki/JsfjMaki.java
A dist/mcp-test/src/test/java/jsf_jmaki/JsfjMakiTest.java
- The automated test and the netbeans empty main class.
M dom/classes/org/mozilla/dom/util/DOMTreeDumper.java
- Introduce preorder traversal callback facility
M webclient/classes_spec/org/mozilla/mcp/MCP.java
- add methods
+ public List<Element> getAnchors(String id) {
+ public List<Element> getAnchors() {
+ public List<Element> getChildElementsWithTagName(Element root,
+ final String tagName) {
+ public List<Element> getChildElementsWithTagName(String id,
+ final String tagName) {
+ public void clickElement(String id) {
+ public void blockingClickElement(Element element) {
SECTION: Diffs
Index: dom/classes/org/mozilla/dom/util/DOMTreeDumper.java
===================================================================
RCS file: /cvsroot/mozilla/java/dom/classes/org/mozilla/dom/util/
DOMTreeDumper.java,v
retrieving revision 1.2
diff -u -r1.2 DOMTreeDumper.java
--- dom/classes/org/mozilla/dom/util/DOMTreeDumper.java 6 Mar 2007
22:03:42 -0000 1.2
+++ dom/classes/org/mozilla/dom/util/DOMTreeDumper.java 21 Apr 2007
03:16:51 -0000
@@ -24,6 +24,7 @@
import java.io.PrintStream;
import java.io.FileOutputStream;
import java.io.IOException;
+import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
@@ -233,34 +234,60 @@
dbg("finished dumping...");
return baos.toString();
}
-
- private Element findElementWithName(Element start, String name) {
- Element result = null;
+ public void preorderTreeWalk(Node start,
+ TreeTraversalCallBack callback, Object closure) {
+ try {
+ doPreorderTreeWalk(start, callback, closure);
+ } catch (AbortTraversalException ex) {
+ return;
+ }
+ }
+
+
+ private void doPreorderTreeWalk(Node start,
+ TreeTraversalCallBack callback, Object closure)
+ throws AbortTraversalException {
+ callback.takeActionOnNode(start, closure);
+ NodeList children = start.getChildNodes();
Node child = null;
- String elementName = start.getAttribute("name");
- if (null != elementName && elementName.equals(name)) {
- return start;
+ int length = 0;
+ boolean hasChildren = ((children != null) &&
+ ((length = children.getLength()) > 0));
+ if (!hasChildren) {
+ return;
}
- else {
- NodeList children = start.getChildNodes();
- int length = 0;
- boolean hasChildren = ((children != null) &&
- ((length = children.getLength()) > 0));
- if (!hasChildren) {
- return result;
- }
- for (int i=0; i < length; i++) {
- child = children.item(i);
- result = null;
- if (child instanceof Element) {
- result = findElementWithName((Element) child,
name);
- }
- if (null != result) {
- break;
+ for (int i=0; i < length; i++) {
+ child = children.item(i);
+ doPreorderTreeWalk(child, callback, closure);
+ }
+ }
+
+ private Element findElementWithName(Element start, final String
name) {
+ TreeTraversalCallBack callback = new TreeTraversalCallBack()
{
+
+ public void takeActionOnNode(Node node, Object closure)
+ throws AbortTraversalException {
+ Element element = null;
+ if (node instanceof Element) {
+ element = (Element) node;
+ String elementName =
element.getAttribute("name");
+ if (null != elementName &&
elementName.equals(name)) {
+ this.setResult(node);
+ throw new AbortTraversalException("Found
result");
+ }
}
}
- }
+
+ };
+
+ Element result = null;
+
+ this.preorderTreeWalk(start, callback, name);
+ Object obj = callback.getResult();
+ if (obj instanceof Element) {
+ result = (Element)obj;
+ }
return result;
}
@@ -280,4 +307,29 @@
System.out.println(name + ": " + str);
}
}
+
+ public static abstract class TreeTraversalCallBack {
+ public abstract void takeActionOnNode(Node node, Object
closure)
+throws AbortTraversalException;
+
+ private Object result;
+
+ public Object getResult() {
+ return result;
+ }
+
+ public void setResult(Object result) {
+ this.result = result;
+ }
+ }
+
+ public static class AbortTraversalException extends
RuntimeException {
+ private Object closure;
+ public AbortTraversalException(Object closure) {
+ this.closure = closure;
+ }
+ public Object getClosure() {
+ return closure;
+ }
+ }
}
Index: webclient/classes_spec/org/mozilla/mcp/MCP.java
===================================================================
RCS file: /cvsroot/mozilla/java/webclient/classes_spec/org/mozilla/mcp/
MCP.java,v
retrieving revision 1.8
diff -u -r1.8 MCP.java
--- webclient/classes_spec/org/mozilla/mcp/MCP.java 14 Mar 2007
21:02:13 -0000 1.8
+++ webclient/classes_spec/org/mozilla/mcp/MCP.java 21 Apr 2007
03:16:51 -0000
@@ -33,11 +33,15 @@
import java.awt.event.KeyListener;
import java.awt.event.MouseListener;
import java.io.FileNotFoundException;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.mozilla.dom.util.DOMTreeDumper;
+import org.mozilla.dom.util.DOMTreeDumper.AbortTraversalException;
+import org.mozilla.dom.util.DOMTreeDumper.TreeTraversalCallBack;
import org.mozilla.webclient.BrowserControl;
import org.mozilla.webclient.BrowserControlCanvas;
import org.mozilla.webclient.BrowserControlFactory;
@@ -49,6 +53,7 @@
import org.mozilla.webclient.WebclientEvent;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
+import org.w3c.dom.Node;
/**
* <p>The main class for the Mozilla Control Program. Please see <a
@@ -110,6 +115,9 @@
}
private void openLatch() {
+ if (null == latch) {
+ return;
+ }
if (null != latch || 1 != latch.getCount()) {
latch.countDown();
latch = null;
@@ -405,6 +413,79 @@
return result;
}
+
+ /**
+
+ * <p>Given an argument <code>id</code>, return a List of DOM
+ * <code>Element</code> instances that are HTML anchors that are
+ * direct or indirect children of the element with that <code>id</
code>.
+ */
+ public List<Element> getAnchors(String id) {
+ List<Element> result = getChildElementsWithTagName(id, "a");
+ return result;
+ }
+
+ /**
+
+ * <p>Return a List of DOM
+ * <code>Element</code> instances that are HTML anchors that are
+ * present in the document.
+ * If no such elements exist,
+ * <code>null</code> is returned.</p>
+ */
+ public List<Element> getAnchors() {
+ Element root =
getCurrentPage().getDOM().getDocumentElement();
+ List<Element> result = getChildElementsWithTagName(root,
"a");
+ return result;
+ }
+
+ /**
+
+ * <p>Return a List of DOM <code>Element</code> instances whose
+ * tagName attribute is equal to the argument <code>tagName</
code>.
+ * If no such elements exist,
+ * <code>null</code> is returned.</p>
+ */
+
+ public List<Element> getChildElementsWithTagName(Element root,
+ final String tagName) {
+ List<Element> results = new ArrayList<Element>();
+ if (null != root) {
+ TreeTraversalCallBack callback = new
TreeTraversalCallBack() {
+ public void takeActionOnNode(Node node, Object
closure)
+ throws AbortTraversalException {
+ List<Element> list = (List<Element>) closure;
+ Element element = null;
+ if (node instanceof Element) {
+ element = (Element) node;
+ String nodeTagName = element.getTagName();
+ if (null != nodeTagName &&
nodeTagName.equalsIgnoreCase(tagName)){
+ list.add(element);
+ }
+ }
+ }
+ };
+ getDOMTreeDumper().preorderTreeWalk(root, callback,
results);
+ }
+
+ return results;
+ }
+ /**
+
+ * <p>Return a List of DOM <code>Element</code> instances whose
+ * tagName attribute is equal to the argument <code>tagName</
code>.
+ * If no such elements exist,
+ * <code>null</code> is returned.</p>
+ */
+
+ public List<Element> getChildElementsWithTagName(String id,
+ final String tagName) {
+ List<Element> results = null;
+ Element root = findElement(id);
+ results = getChildElementsWithTagName(root, tagName);
+
+ return results;
+ }
/**
@@ -432,9 +513,9 @@
*/
- public void clickElement(String id) {
- Element element = findElement(id);
+ public void clickElement(Element element) {
String clientX = null, clientY = null;
+ String id = element.getAttribute("id");
if (null != element) {
clientX = element.getAttribute("clientX");
clientY = element.getAttribute("clientY");
@@ -444,7 +525,6 @@
x = Integer.valueOf(clientX).intValue();
y = Integer.valueOf(clientY).intValue();
Robot robot = getRobot();
- createLatch();
robot.mouseMove(x, y);
robot.mousePress(InputEvent.BUTTON1_MASK);
robot.mouseRelease(InputEvent.BUTTON1_MASK);
@@ -466,16 +546,34 @@
* <p>Find the DOM element within the current page matching the
* argument <code>id</code> using [EMAIL PROTECTED] #findElement}. Use
+ * <code>java.awt.Robot</code> to click the element. Return
+ * immediately after clicking the element.</p>
+
+ */
+
+ public void clickElement(String id) {
+ Element element = findElement(id);
+ if (null != element) {
+ clickElement(element);
+ }
+ }
+
+
+ /**
+
+ * <p>Find the DOM element within the current page matching the
+ * argument <code>id</code> using [EMAIL PROTECTED] #findElement}. Use
* <code>java.awt.Robot</code> to click the element. Block until
the
* document load triggered by the click has completed.</p>
*/
- public void blockingClickElement(String idOrName) {
+ public void blockingClickElement(Element element) {
synchronized (this) {
try {
- clickElement(idOrName);
+ createLatch();
+ clickElement(element);
lockLatch();
}
catch (InterruptedException ie) {
@@ -488,6 +586,23 @@
/**
+ * <p>Find the DOM element within the current page matching the
+ * argument <code>id</code> using [EMAIL PROTECTED] #findElement}. Use
+ * <code>java.awt.Robot</code> to click the element. Block until
the
+ * document load triggered by the click has completed.</p>
+
+ */
+
+
+ public void blockingClickElement(String idOrName) {
+ Element element = findElement(idOrName);
+ if (null != element) {
+ blockingClickElement(element);
+ }
+ }
+
+ /**
+
* <p>Load the url, blocking until the load has completed.</p>
*/
_______________________________________________
dev-embedding mailing list
[email protected]
https://lists.mozilla.org/listinfo/dev-embedding