1 package com.atlassian.webdriver.rule;
2
3 import com.atlassian.webdriver.debug.JavaScriptErrorInfo;
4 import com.atlassian.webdriver.debug.JavaScriptErrorRetriever;
5 import com.atlassian.webdriver.testing.rule.JavaScriptErrorsRule;
6
7 import com.google.common.base.Function;
8 import com.google.common.collect.Lists;
9
10 import org.junit.Before;
11 import org.junit.Test;
12 import org.junit.runner.Description;
13 import org.junit.runner.RunWith;
14 import org.mockito.Mock;
15 import org.mockito.runners.MockitoJUnitRunner;
16 import org.openqa.selenium.WebDriver;
17 import org.openqa.selenium.firefox.FirefoxDriver;
18 import org.slf4j.Logger;
19
20 import java.util.List;
21
22 import static com.google.common.collect.Iterables.transform;
23 import static org.hamcrest.MatcherAssert.assertThat;
24 import static org.hamcrest.Matchers.containsString;
25 import static org.hamcrest.core.IsEqual.equalTo;
26 import static org.mockito.Mockito.mock;
27 import static org.mockito.Mockito.verify;
28 import static org.mockito.Mockito.verifyNoMoreInteractions;
29
30
31
32
33
34
35 @RunWith(MockitoJUnitRunner.class)
36 public class TestJavaScriptErrorsRule
37 {
38 @Mock private Logger mockLogger;
39
40 private boolean errorRetrievalSupported = true;
41 private List<String> errorsFound;
42
43 @Before
44 public void setUp()
45 {
46 errorsFound = Lists.newArrayList();
47 }
48
49 @Test
50 public void testOutputsSpecialMessageWhenCannotRetrieveConsoleErrorsOnTestFailed() throws Exception
51 {
52 errorRetrievalSupported = false;
53
54 final WebDriver driver = mock(WebDriver.class);
55 final JavaScriptErrorsRule rule = createRule(driver);
56
57 rule.finished(Description.createTestDescription(TestJavaScriptErrorsRule.class, "testMethod"));
58 verify(mockLogger).info("Unable to provide console output. Console output is currently only supported on Firefox.");
59 verifyNoMoreInteractions(mockLogger);
60 }
61
62 @Test
63 public void testLogsWhenNoErrorsFound()
64 {
65 final FirefoxDriver driver = mock(FirefoxDriver.class);
66 final JavaScriptErrorsRule rule = createRule(driver);
67
68 rule.finished(Description.createTestDescription(TestJavaScriptErrorsRule.class, "testMethod"));
69 verify(mockLogger).info("----- Test '{}' finished with 0 JS errors. ", "testMethod");
70 verifyNoMoreInteractions(mockLogger);
71 }
72
73 @Test
74 public void testLogsWhenErrorsFound()
75 {
76 final FirefoxDriver driver = mock(FirefoxDriver.class);
77 final JavaScriptErrorsRule rule = createRule(driver);
78
79 errorsFound.add("first");
80 errorsFound.add("second");
81
82 rule.finished(Description.createTestDescription(TestJavaScriptErrorsRule.class, "testMethod"));
83 verify(mockLogger).warn("----- Test '{}' finished with {} JS error(s). ", "testMethod", 2);
84 verify(mockLogger).warn("----- START CONSOLE OUTPUT DUMP\n\n{}\n", "error: first\nerror: second");
85 verify(mockLogger).warn("----- END CONSOLE OUTPUT DUMP");
86 verifyNoMoreInteractions(mockLogger);
87 }
88
89 @Test
90 public void testCanBeOverriddenToFailTestWhenErrorsFound()
91 {
92 final FirefoxDriver driver = mock(FirefoxDriver.class);
93 final JavaScriptErrorsRule rule = createRule(driver)
94 .failOnJavaScriptErrors(true);
95
96 errorsFound.add("TypeError: $ is not a function");
97
98 try
99 {
100 rule.finished(Description.createTestDescription(TestJavaScriptErrorsRule.class, "testMethod"));
101 assertThat("Expected an exception to be thrown, but wasn't", true, equalTo(false));
102 }
103 catch (RuntimeException e)
104 {
105 assertThat(e.getMessage(), containsString("Test failed due to javascript errors being detected"));
106 }
107 verify(mockLogger).warn("----- Test '{}' finished with {} JS error(s). ", "testMethod", 1);
108 }
109
110 private JavaScriptErrorsRule createRule(final WebDriver driver)
111 {
112 return new JavaScriptErrorsRule(driver)
113 .errorRetriever(new MockErrorRetriever())
114 .logger(mockLogger);
115 }
116
117 private class MockErrorRetriever implements JavaScriptErrorRetriever
118 {
119 @Override
120 public boolean isErrorRetrievalSupported()
121 {
122 return errorRetrievalSupported;
123 }
124
125 @Override
126 public Iterable<JavaScriptErrorInfo> getErrors()
127 {
128 return transform(errorsFound, new Function<String, JavaScriptErrorInfo>()
129 {
130 public JavaScriptErrorInfo apply(final String message)
131 {
132 return new JavaScriptErrorInfo()
133 {
134 public String getDescription()
135 {
136 return "error: " + message;
137 }
138
139 public String getMessage()
140 {
141 return message;
142 }
143 };
144 }
145 });
146 }
147 }
148 }