Commit f76f0d3e4337dd31db68575d8b13f1f4062f511c

Authored by bernard
1 parent 5bc796f3

Implemented method for executing ajax re-rendered scripts.

Implemented several tests for ClassDetails.
@@ -43,6 +43,17 @@ @@ -43,6 +43,17 @@
43 <optimize>false</optimize> 43 <optimize>false</optimize>
44 </configuration> 44 </configuration>
45 </plugin> 45 </plugin>
  46 + <plugin>
  47 + <groupId>org.apache.maven.plugins</groupId>
  48 + <artifactId>maven-source-plugin</artifactId>
  49 + <executions>
  50 + <execution>
  51 + <goals>
  52 + <goal>jar</goal>
  53 + </goals>
  54 + </execution>
  55 + </executions>
  56 + </plugin>
46 57
47 </plugins> 58 </plugins>
48 </build> 59 </build>
@@ -7,9 +7,13 @@ import org.apache.commons.logging.Log; @@ -7,9 +7,13 @@ import org.apache.commons.logging.Log;
7 import org.apache.commons.logging.LogFactory; 7 import org.apache.commons.logging.LogFactory;
8 import org.w3c.dom.Node; 8 import org.w3c.dom.Node;
9 9
  10 +import java.util.HashSet;
  11 +import java.util.Set;
  12 +
10 public class DomChangeLogger implements DomChangeListener { 13 public class DomChangeLogger implements DomChangeListener {
11 14
12 private static final Log LOG = LogFactory.getLog(DomChangeLogger.class); 15 private static final Log LOG = LogFactory.getLog(DomChangeLogger.class);
  16 + private Set<String> detailIds = new HashSet<String>();
13 17
14 public void nodeAdded(DomChangeEvent event) { 18 public void nodeAdded(DomChangeEvent event) {
15 logEvent(event, "added"); 19 logEvent(event, "added");
@@ -19,6 +23,14 @@ public class DomChangeLogger implements DomChangeListener { @@ -19,6 +23,14 @@ public class DomChangeLogger implements DomChangeListener {
19 logEvent(event, "removed"); 23 logEvent(event, "removed");
20 } 24 }
21 25
  26 + public void showDetails(String id) {
  27 + detailIds.add(id);
  28 + }
  29 +
  30 + public void hideDetails(String id) {
  31 + detailIds.remove(id);
  32 + }
  33 +
22 private void logEvent(DomChangeEvent event, String action) { 34 private void logEvent(DomChangeEvent event, String action) {
23 String changed; 35 String changed;
24 final DomNode changedNode = event.getChangedNode(); 36 final DomNode changedNode = event.getChangedNode();
@@ -36,7 +48,7 @@ public class DomChangeLogger implements DomChangeListener { @@ -36,7 +48,7 @@ public class DomChangeLogger implements DomChangeListener {
36 } 48 }
37 LOG.info("DomChangeEvent[action=" + action + ";changedElement=" + changed + ";source=" + event.getSource() + ";parent=" + parent + "]"); 49 LOG.info("DomChangeEvent[action=" + action + ";changedElement=" + changed + ";source=" + event.getSource() + ";parent=" + parent + "]");
38 final Node id = event.getChangedNode().getAttributes().getNamedItem("id"); 50 final Node id = event.getChangedNode().getAttributes().getNamedItem("id");
39 - if (id != null && "searchClass:searchStudent".equals(id.getTextContent())) { 51 + if (id != null && detailIds.contains(id.getTextContent())) {
40 LOG.info(event.getChangedNode().asXml()); 52 LOG.info(event.getChangedNode().asXml());
41 } 53 }
42 } 54 }
1 package pl.labno.bernard.htmlunified; 1 package pl.labno.bernard.htmlunified;
2 2
3 import com.gargoylesoftware.htmlunit.WebClient; 3 import com.gargoylesoftware.htmlunit.WebClient;
  4 +import com.gargoylesoftware.htmlunit.html.DomNode;
4 import com.gargoylesoftware.htmlunit.html.DomNodeList; 5 import com.gargoylesoftware.htmlunit.html.DomNodeList;
5 import com.gargoylesoftware.htmlunit.html.HtmlElement; 6 import com.gargoylesoftware.htmlunit.html.HtmlElement;
  7 +import com.gargoylesoftware.htmlunit.html.HtmlPage;
6 import com.gargoylesoftware.htmlunit.html.HtmlTableCell; 8 import com.gargoylesoftware.htmlunit.html.HtmlTableCell;
7 9
  10 +import java.util.ArrayList;
8 import java.util.HashMap; 11 import java.util.HashMap;
  12 +import java.util.List;
9 import java.util.Map; 13 import java.util.Map;
10 14
11 public class WebClientUtils { 15 public class WebClientUtils {
@@ -29,19 +33,27 @@ public class WebClientUtils { @@ -29,19 +33,27 @@ public class WebClientUtils {
29 WebClientUtils.defaultTimeout = defaultTimeout; 33 WebClientUtils.defaultTimeout = defaultTimeout;
30 } 34 }
31 35
32 - public static int waitForJSJob(WebClient webClient) {  
33 - return waitForJSJob(webClient, webClient.waitForBackgroundJavaScript(10) - 1); 36 + public static int waitForJSJob(String message, WebClient webClient) {
  37 + return waitForJSJob(message, webClient, webClient.waitForBackgroundJavaScript(10) - 1);
34 } 38 }
35 39
36 - public static int waitForJSJob(WebClient webClient, int initialJobCount) {  
37 - return waitForJSJob(webClient, initialJobCount, defaultTimeout); 40 + public static int waitForJSJob(String message, WebClient webClient, int initialJobCount) {
  41 + return waitForJSJob(message, webClient, initialJobCount, defaultTimeout);
38 } 42 }
39 43
40 - public static int waitForJSJob(WebClient webClient, int initialJobCount, long timeout) {  
41 - return waitForJSJob(webClient, initialJobCount, timeout, defaultCheckInterval); 44 + public static int waitForJSJob(WebClient webClient, int initialJobCount, int timeout) {
  45 + return waitForJSJob(null, webClient, initialJobCount, timeout);
42 } 46 }
43 47
44 - public static int waitForJSJob(WebClient webClient, int initialJobCount, long timeout, long checkInterval) { 48 + public static int waitForJSJob(String message, WebClient webClient, int initialJobCount, long timeout) {
  49 + return waitForJSJob(message, webClient, initialJobCount, timeout, defaultCheckInterval);
  50 + }
  51 +
  52 + public static int waitForJSJob(String message, WebClient webClient, int initialJobCount, int timeout) {
  53 + return waitForJSJob(message, webClient, initialJobCount, timeout, defaultCheckInterval);
  54 + }
  55 +
  56 + public static int waitForJSJob(String message, WebClient webClient, int initialJobCount, long timeout, long checkInterval) {
45 int jobs; 57 int jobs;
46 long startTime = System.currentTimeMillis(); 58 long startTime = System.currentTimeMillis();
47 do { 59 do {
@@ -50,7 +62,7 @@ public class WebClientUtils { @@ -50,7 +62,7 @@ public class WebClientUtils {
50 throw new RuntimeException("Number of JavaScript jobs doesn't drop to initial level for " + timeout + " seconds. It's memory leak in your JavaScript rather then request taking so long!"); 62 throw new RuntimeException("Number of JavaScript jobs doesn't drop to initial level for " + timeout + " seconds. It's memory leak in your JavaScript rather then request taking so long!");
51 } 63 }
52 } while (jobs > initialJobCount); 64 } while (jobs > initialJobCount);
53 - System.out.println("Waiting took: " + (System.currentTimeMillis() - startTime) + "ms"); 65 + System.out.println("Waiting" + (message == null ? "" : " for " + message) + " took: " + (System.currentTimeMillis() - startTime) + "ms");
54 return jobs; 66 return jobs;
55 } 67 }
56 68
@@ -88,4 +100,32 @@ public class WebClientUtils { @@ -88,4 +100,32 @@ public class WebClientUtils {
88 } 100 }
89 } while (startTime + timeout > System.currentTimeMillis()); 101 } while (startTime + timeout > System.currentTimeMillis());
90 } 102 }
  103 +
  104 + public static void executeAjaxReRenderedScripts(HtmlPage page) {
  105 + final DomNodeList<HtmlElement> scripts = page.getElementsByTagName("script");
  106 + /**
  107 + * We cannot iterate over html DomNodeList cause it depends on sibling relationship which we will modify.
  108 + */
  109 + final List<HtmlElement> scriptsList = new ArrayList<HtmlElement>();
  110 + for (HtmlElement element : scripts) {
  111 + scriptsList.add(element);
  112 + }
  113 + for (HtmlElement element : scriptsList) {
  114 + if (element.getChildNodes().size() > 1) {
  115 + element.removeChild(element.getFirstChild());
  116 + final DomNode sibling = element.getNextSibling();
  117 + final DomNode parentNode = element.getParentNode();
  118 + /**
  119 + * Script will be executed upon inserting into DOM tree, so we removed and add it again.
  120 + */
  121 + if (sibling != null) {
  122 + parentNode.removeChild(element);
  123 + sibling.insertBefore(element);
  124 + } else {
  125 + parentNode.removeChild(element);
  126 + parentNode.appendChild(element);
  127 + }
  128 + }
  129 + }
  130 + }
91 } 131 }
  1 +package pl.labno.bernard.htmlunified;
  2 +
  3 +import com.gargoylesoftware.htmlunit.BrowserVersion;
  4 +import com.gargoylesoftware.htmlunit.WebClient;
  5 +import com.gargoylesoftware.htmlunit.html.HtmlElement;
  6 +import com.gargoylesoftware.htmlunit.html.HtmlInput;
  7 +import com.gargoylesoftware.htmlunit.html.HtmlPage;
  8 +import com.gargoylesoftware.htmlunit.html.HtmlSpan;
  9 +import org.junit.Assert;
  10 +import org.junit.Test;
  11 +
  12 +import java.io.IOException;
  13 +import java.util.List;
  14 +
  15 +public class ClassDetailsTest {
  16 +
  17 + @Test
  18 + public void openDetailsModalPanel() throws IOException {
  19 + WebClient client = new WebClient(BrowserVersion.FIREFOX_3_6);
  20 + HtmlPage page = login(client);
  21 + @SuppressWarnings("unchecked")
  22 + final List<HtmlSpan> titleElements = (List<HtmlSpan>) page.getElementById("results:schedule").getByXPath(".//span[@class='fc-event-title']");
  23 + Assert.assertNotSame(0, titleElements.size());
  24 + new RequestResponseLogger(client);
  25 + page.addDomChangeListener(new DomChangeLogger());
  26 + WebClientUtils.waitForJSJob("initial javascript to finish", client, 0, 30000);
  27 + System.out.println("item:" + titleElements.get(0).asText());
  28 + ((HtmlElement) titleElements.get(0).getParentNode()).mouseOver();
  29 + ((HtmlElement) titleElements.get(0).getParentNode()).click();
  30 + WebClientUtils.waitForJSJob("classDetailsModalPanel shown after schedule event clicked", client, 0, 30000);
  31 + Assert.assertNotNull(page.getElementById("classDetailsModalPanelContainer"));
  32 + }
  33 +
  34 + @Test
  35 + public void closeDetailsModalPanel() throws IOException {
  36 + WebClient client = new WebClient(BrowserVersion.FIREFOX_3_6);
  37 + HtmlPage page = login(client);
  38 + @SuppressWarnings("unchecked")
  39 + final List<HtmlSpan> titleElements = (List<HtmlSpan>) page.getElementById("results:schedule").getByXPath(".//span[@class='fc-event-title']");
  40 + Assert.assertNotSame(0, titleElements.size());
  41 +// new RequestResponseLogger(client);
  42 +// page.addDomChangeListener(new DomChangeLogger());
  43 + WebClientUtils.waitForJSJob("initial javascript to finish", client, 0, 30000);
  44 + System.out.println("item:" + titleElements.get(0).asText());
  45 + ((HtmlElement) titleElements.get(0).getParentNode()).mouseOver();
  46 + ((HtmlElement) titleElements.get(0).getParentNode()).click();
  47 + WebClientUtils.waitForJSJob("classDetailsModalPanel shown after schedule event clicked", client, 0, 30000);
  48 + Assert.assertNotNull(page.getElementById("classDetailsModalPanelContainer"));
  49 + ((HtmlElement) page.getElementById("classDetailsModalPanelContainer").getByXPath("//*[contains(@src,'close.png')]").get(0)).click();
  50 + WebClientUtils.waitForJSJob("classDetailsModalPanel hidden after cancel button", client, 0, 30000);
  51 + Assert.assertNull(page.getElementById("classDetailsModalPanelContainer"));
  52 + }
  53 +
  54 + @Test
  55 + public void removeClass() throws IOException {
  56 + WebClient client = new WebClient(BrowserVersion.FIREFOX_2);
  57 + final RequestResponseLogger requestResponseLogger = new RequestResponseLogger(client);
  58 + requestResponseLogger.off();
  59 + HtmlPage page = login(client);
  60 + @SuppressWarnings("unchecked")
  61 + final List<HtmlSpan> titleElements = (List<HtmlSpan>) page.getElementById("results:schedule").getByXPath(".//span[@class='fc-event-title']");
  62 + Assert.assertEquals(6, titleElements.size());
  63 + Assert.assertNotSame(0, titleElements.size());
  64 + WebClientUtils.waitForJSJob("initial javascript to finish", client, 0, 30000);
  65 +
  66 + client.setAlertHandler(new AlertLogger());
  67 + final DomChangeLogger domChangeLogger = new DomChangeLogger();
  68 + domChangeLogger.showDetails("results:j_id2158");
  69 +// page.addDomChangeListener(domChangeLogger);
  70 +// page.addHtmlAttsributeChangeListener(new HtmlAttributeChangeLogger());
  71 +// requestResponseLogger.on();
  72 +
  73 + ((HtmlElement) titleElements.get(0).getParentNode()).mouseOver();
  74 + ((HtmlElement) titleElements.get(0).getParentNode()).click();
  75 + WebClientUtils.waitForJSJob("classDetailsModalPanel shown after schedule event clicked", client, 0, 30000);
  76 + WebClientUtils.executeAjaxReRenderedScripts(page);
  77 + Assert.assertNotNull(page.getElementById("classDetailsModalPanelContainer"));
  78 + ((HtmlElement) page.getElementById("classDetailsModalPanelContainer").getByXPath("//*[contains(@src,'remove.png')]").get(0)).click();
  79 + WebClientUtils.waitForJSJob("classDetailsModalPanel hidden after remove button", client, 0, 30000);
  80 + WebClientUtils.executeAjaxReRenderedScripts(page);
  81 + WebClientUtils.waitForJSJob("schedule refresh", client, 0, 30000);
  82 + Assert.assertNull(page.getElementById("classDetailsModalPanelContainer"));
  83 + Assert.assertEquals(5, page.getElementById("results:schedule").getByXPath(".//span[@class='fc-event-title']").size());
  84 + }
  85 +
  86 + private HtmlPage login(WebClient client) throws IOException {
  87 + HtmlPage page = (HtmlPage) client.getPage("http://localhost:8080/schoolmanager/view/class/current.seam?networkId=salsafactory");
  88 + ((HtmlInput) page.getElementById("loginForm:email")).setValueAttribute("it.crowd.test@gmail.com");
  89 + ((HtmlInput) page.getElementById("loginForm:password")).setValueAttribute("aaaaa");
  90 + HtmlPage oldPage = page;
  91 + page = page.getElementById("loginForm:submit").click();
  92 +// This assert would fail (when page redidrects than you need to obtain new page)
  93 +// Assert.assertEquals(page,oldPage);
  94 + Assert.assertEquals(client.getCurrentWindow().getEnclosedPage(), page);
  95 + return page;
  96 + }
  97 +}
1 package pl.labno.bernard.htmlunified; 1 package pl.labno.bernard.htmlunified;
2 2
3 import com.gargoylesoftware.htmlunit.BrowserVersion; 3 import com.gargoylesoftware.htmlunit.BrowserVersion;
  4 +import com.gargoylesoftware.htmlunit.CollectingAlertHandler;
4 import com.gargoylesoftware.htmlunit.NicelyResynchronizingAjaxController; 5 import com.gargoylesoftware.htmlunit.NicelyResynchronizingAjaxController;
5 import com.gargoylesoftware.htmlunit.WebClient; 6 import com.gargoylesoftware.htmlunit.WebClient;
6 import com.gargoylesoftware.htmlunit.html.HtmlPage; 7 import com.gargoylesoftware.htmlunit.html.HtmlPage;
@@ -8,11 +9,12 @@ import org.junit.Assert; @@ -8,11 +9,12 @@ import org.junit.Assert;
8 import org.junit.Test; 9 import org.junit.Test;
9 10
10 import java.io.IOException; 11 import java.io.IOException;
  12 +import java.util.ArrayList;
11 13
12 public class SandboxTest { 14 public class SandboxTest {
13 15
14 @Test 16 @Test
15 - public void test() throws IOException { 17 + public void testClickImage() throws IOException {
16 final WebClient client = new WebClient(BrowserVersion.FIREFOX_3_6); 18 final WebClient client = new WebClient(BrowserVersion.FIREFOX_3_6);
17 client.setAjaxController(new NicelyResynchronizingAjaxController()); 19 client.setAjaxController(new NicelyResynchronizingAjaxController());
18 HtmlPage page = (HtmlPage) client.getPage("file:./target/test-classes/sandbox.html"); 20 HtmlPage page = (HtmlPage) client.getPage("file:./target/test-classes/sandbox.html");
@@ -20,4 +22,23 @@ public class SandboxTest { @@ -20,4 +22,23 @@ public class SandboxTest {
20 page.getElementById("close").click(); 22 page.getElementById("close").click();
21 Assert.assertEquals("", page.getElementById("elementToHide").asText()); 23 Assert.assertEquals("", page.getElementById("elementToHide").asText());
22 } 24 }
  25 +
  26 + @Test
  27 + public void testClickJQueryBoundElement() throws IOException {
  28 + final WebClient client = new WebClient(BrowserVersion.FIREFOX_3_6);
  29 + client.setAjaxController(new NicelyResynchronizingAjaxController());
  30 + HtmlPage page = (HtmlPage) client.getPage("file:./target/test-classes/sandbox.html");
  31 + final ArrayList<String> alerts = new ArrayList<String>();
  32 + client.setAlertHandler(new CollectingAlertHandler(alerts));
  33 + page.getElementById("clickable").click();
  34 + System.out.println(alerts);
  35 + Assert.assertEquals(1, alerts.size());
  36 + Assert.assertEquals("Clicked clickable", alerts.get(0));
  37 +
  38 + alerts.clear();
  39 + page.getElementById("clickable2child").click();
  40 + System.out.println(alerts);
  41 + Assert.assertEquals(1, alerts.size());
  42 + Assert.assertEquals("Clicked clickable2", alerts.get(0));
  43 + }
23 } 44 }
@@ -30,7 +30,7 @@ public class ScheduleTest { @@ -30,7 +30,7 @@ public class ScheduleTest {
30 for (HtmlSpan o : titleElements) { 30 for (HtmlSpan o : titleElements) {
31 titles.add(o.asText()); 31 titles.add(o.asText());
32 } 32 }
33 - Assert.assertEquals(4, titles.size()); 33 + Assert.assertEquals(6, titles.size());
34 } 34 }
35 35
36 @Test 36 @Test
@@ -58,7 +58,6 @@ public class ScheduleTest { @@ -58,7 +58,6 @@ public class ScheduleTest {
58 System.out.println("Success!"); 58 System.out.println("Success!");
59 59
60 60
61 -// page = (HtmlPage) client.getPage("http://localhost:8080/schoolmanager/view/class/current.seam?networkId=salsafactory");  
62 WebClientUtils.waitForJSJob(client, 0, 30000); 61 WebClientUtils.waitForJSJob(client, 0, 30000);
63 Assert.assertEquals(client.getCurrentWindow().getEnclosedPage(), page); 62 Assert.assertEquals(client.getCurrentWindow().getEnclosedPage(), page);
64 studentInput = (HtmlInput) page.getElementById("searchClass:student_i"); 63 studentInput = (HtmlInput) page.getElementById("searchClass:student_i");
@@ -66,7 +65,6 @@ public class ScheduleTest { @@ -66,7 +65,6 @@ public class ScheduleTest {
66 studentInput.type('l'); 65 studentInput.type('l');
67 studentInput.type('i'); 66 studentInput.type('i');
68 Assert.assertEquals(client.getCurrentWindow().getEnclosedPage(), page); 67 Assert.assertEquals(client.getCurrentWindow().getEnclosedPage(), page);
69 -// WebClientUtils.forceWait(2000);  
70 // Here the suggestionBox is still hidden 68 // Here the suggestionBox is still hidden
71 WebClientUtils.waitForJSJob(client, 0, 30000); 69 WebClientUtils.waitForJSJob(client, 0, 30000);
72 // Here suggestionBox is visible 70 // Here suggestionBox is visible
@@ -138,7 +136,7 @@ public class ScheduleTest { @@ -138,7 +136,7 @@ public class ScheduleTest {
138 136
139 private HtmlPage login(WebClient client) throws IOException { 137 private HtmlPage login(WebClient client) throws IOException {
140 HtmlPage page = (HtmlPage) client.getPage("http://localhost:8080/schoolmanager/view/class/current.seam?networkId=salsafactory"); 138 HtmlPage page = (HtmlPage) client.getPage("http://localhost:8080/schoolmanager/view/class/current.seam?networkId=salsafactory");
141 - ((HtmlInput) page.getElementById("loginForm:email")).setValueAttribute("s4237@pjwstk.edu.pl"); 139 + ((HtmlInput) page.getElementById("loginForm:email")).setValueAttribute("it.crowd.test@gmail.com");
142 ((HtmlInput) page.getElementById("loginForm:password")).setValueAttribute("aaaaa"); 140 ((HtmlInput) page.getElementById("loginForm:password")).setValueAttribute("aaaaa");
143 HtmlPage oldPage = page; 141 HtmlPage oldPage = page;
144 page = page.getElementById("loginForm:submit").click(); 142 page = page.getElementById("loginForm:submit").click();
This diff could not be displayed because it is too large.
@@ -3,10 +3,28 @@ @@ -3,10 +3,28 @@
3 <html> 3 <html>
4 <head> 4 <head>
5 <title></title> 5 <title></title>
  6 + <script type="text/javascript" src="jquery-1.3.2.js"></script>
  7 + <script type="text/javascript">
  8 + jQuery(function() {
  9 + jQuery("#clickable").click(function() {
  10 + alert("Clicked " + this.id);
  11 + });
  12 + jQuery("#clickable2").click(function() {
  13 + alert("Clicked " + this.id);
  14 + });
  15 + });
  16 + </script>
6 </head> 17 </head>
7 <body> 18 <body>
8 <img id="close" onclick="var e = document.getElementById('elementToHide');e.removeChild(e.firstChild)" alt="close"/> 19 <img id="close" onclick="var e = document.getElementById('elementToHide');e.removeChild(e.firstChild)" alt="close"/>
9 20
10 <div id="elementToHide">elementToHide</div> 21 <div id="elementToHide">elementToHide</div>
  22 +
  23 +<div id="clickable">Click me</div>
  24 +<div id="clickable2">
  25 + <a>
  26 + <span id="clickable2child">Clickable child</span>
  27 + </a>
  28 +</div>
11 </body> 29 </body>
12 </html> 30 </html>
Please register or login to post a comment