Commit f76f0d3e4337dd31db68575d8b13f1f4062f511c
1 parent
5bc796f3
Implemented method for executing ajax re-rendered scripts.
Implemented several tests for ClassDetails.
Showing
8 changed files
with
211 additions
and
14 deletions
... | ... | @@ -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(); | ... | ... |
src/test/resources/jquery-1.3.2.js
0 → 100644
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