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 43 <optimize>false</optimize>
44 44 </configuration>
45 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 58 </plugins>
48 59 </build>
... ...
... ... @@ -7,9 +7,13 @@ import org.apache.commons.logging.Log;
7 7 import org.apache.commons.logging.LogFactory;
8 8 import org.w3c.dom.Node;
9 9
  10 +import java.util.HashSet;
  11 +import java.util.Set;
  12 +
10 13 public class DomChangeLogger implements DomChangeListener {
11 14
12 15 private static final Log LOG = LogFactory.getLog(DomChangeLogger.class);
  16 + private Set<String> detailIds = new HashSet<String>();
13 17
14 18 public void nodeAdded(DomChangeEvent event) {
15 19 logEvent(event, "added");
... ... @@ -19,6 +23,14 @@ public class DomChangeLogger implements DomChangeListener {
19 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 34 private void logEvent(DomChangeEvent event, String action) {
23 35 String changed;
24 36 final DomNode changedNode = event.getChangedNode();
... ... @@ -36,7 +48,7 @@ public class DomChangeLogger implements DomChangeListener {
36 48 }
37 49 LOG.info("DomChangeEvent[action=" + action + ";changedElement=" + changed + ";source=" + event.getSource() + ";parent=" + parent + "]");
38 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 52 LOG.info(event.getChangedNode().asXml());
41 53 }
42 54 }
... ...
1 1 package pl.labno.bernard.htmlunified;
2 2
3 3 import com.gargoylesoftware.htmlunit.WebClient;
  4 +import com.gargoylesoftware.htmlunit.html.DomNode;
4 5 import com.gargoylesoftware.htmlunit.html.DomNodeList;
5 6 import com.gargoylesoftware.htmlunit.html.HtmlElement;
  7 +import com.gargoylesoftware.htmlunit.html.HtmlPage;
6 8 import com.gargoylesoftware.htmlunit.html.HtmlTableCell;
7 9
  10 +import java.util.ArrayList;
8 11 import java.util.HashMap;
  12 +import java.util.List;
9 13 import java.util.Map;
10 14
11 15 public class WebClientUtils {
... ... @@ -29,19 +33,27 @@ public class WebClientUtils {
29 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 57 int jobs;
46 58 long startTime = System.currentTimeMillis();
47 59 do {
... ... @@ -50,7 +62,7 @@ public class WebClientUtils {
50 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 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 66 return jobs;
55 67 }
56 68
... ... @@ -88,4 +100,32 @@ public class WebClientUtils {
88 100 }
89 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 1 package pl.labno.bernard.htmlunified;
2 2
3 3 import com.gargoylesoftware.htmlunit.BrowserVersion;
  4 +import com.gargoylesoftware.htmlunit.CollectingAlertHandler;
4 5 import com.gargoylesoftware.htmlunit.NicelyResynchronizingAjaxController;
5 6 import com.gargoylesoftware.htmlunit.WebClient;
6 7 import com.gargoylesoftware.htmlunit.html.HtmlPage;
... ... @@ -8,11 +9,12 @@ import org.junit.Assert;
8 9 import org.junit.Test;
9 10
10 11 import java.io.IOException;
  12 +import java.util.ArrayList;
11 13
12 14 public class SandboxTest {
13 15
14 16 @Test
15   - public void test() throws IOException {
  17 + public void testClickImage() throws IOException {
16 18 final WebClient client = new WebClient(BrowserVersion.FIREFOX_3_6);
17 19 client.setAjaxController(new NicelyResynchronizingAjaxController());
18 20 HtmlPage page = (HtmlPage) client.getPage("file:./target/test-classes/sandbox.html");
... ... @@ -20,4 +22,23 @@ public class SandboxTest {
20 22 page.getElementById("close").click();
21 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 30 for (HtmlSpan o : titleElements) {
31 31 titles.add(o.asText());
32 32 }
33   - Assert.assertEquals(4, titles.size());
  33 + Assert.assertEquals(6, titles.size());
34 34 }
35 35
36 36 @Test
... ... @@ -58,7 +58,6 @@ public class ScheduleTest {
58 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 61 WebClientUtils.waitForJSJob(client, 0, 30000);
63 62 Assert.assertEquals(client.getCurrentWindow().getEnclosedPage(), page);
64 63 studentInput = (HtmlInput) page.getElementById("searchClass:student_i");
... ... @@ -66,7 +65,6 @@ public class ScheduleTest {
66 65 studentInput.type('l');
67 66 studentInput.type('i');
68 67 Assert.assertEquals(client.getCurrentWindow().getEnclosedPage(), page);
69   -// WebClientUtils.forceWait(2000);
70 68 // Here the suggestionBox is still hidden
71 69 WebClientUtils.waitForJSJob(client, 0, 30000);
72 70 // Here suggestionBox is visible
... ... @@ -138,7 +136,7 @@ public class ScheduleTest {
138 136
139 137 private HtmlPage login(WebClient client) throws IOException {
140 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 140 ((HtmlInput) page.getElementById("loginForm:password")).setValueAttribute("aaaaa");
143 141 HtmlPage oldPage = page;
144 142 page = page.getElementById("loginForm:submit").click();
... ...
This diff could not be displayed because it is too large.
... ... @@ -3,10 +3,28 @@
3 3 <html>
4 4 <head>
5 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 17 </head>
7 18 <body>
8 19 <img id="close" onclick="var e = document.getElementById('elementToHide');e.removeChild(e.firstChild)" alt="close"/>
9 20
10 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 29 </body>
12 30 </html>
\ No newline at end of file
... ...
Please register or login to post a comment