1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package org.htmlunit.junit;
16
17 import java.io.ByteArrayOutputStream;
18 import java.io.OutputStream;
19 import java.io.PrintStream;
20 import java.util.Optional;
21 import java.util.regex.Pattern;
22
23 import org.apache.commons.lang3.StringUtils;
24 import org.htmlunit.WebDriverTestCase;
25 import org.junit.jupiter.api.extension.AfterEachCallback;
26 import org.junit.jupiter.api.extension.BeforeEachCallback;
27 import org.junit.jupiter.api.extension.ExtensionContext;
28
29
30
31
32
33
34
35
36
37
38
39 public class ErrorOutputChecker implements BeforeEachCallback, AfterEachCallback {
40 private PrintStream originalErr_;
41 private final ByteArrayOutputStream baos_ = new ByteArrayOutputStream();
42 private static final Pattern[] PATTERNS = {
43
44 Pattern.compile(".*Logging initialized .* to org.eclipse.jetty.util.log.StdErrLog.*\r?\n"),
45
46
47 Pattern.compile("SLF4J\\(I\\): .*\r?\n"),
48
49
50 Pattern.compile(".*com.caucho.quercus.servlet.QuercusServlet initImpl\r?\n"),
51 Pattern.compile(".*QuercusServlet starting as QuercusServletImpl\r?\n"),
52 Pattern.compile(".*Quercus finished initialization in \\d*ms\r?\n"),
53
54
55 Pattern.compile("ERROR: 'Use of the extension function .*\r?\n"),
56 };
57
58 @Override
59 public void beforeEach(final ExtensionContext context) throws Exception {
60 wrapSystemErr();
61 }
62
63 @Override
64 public void afterEach(final ExtensionContext context) throws Exception {
65 try {
66 final Optional<Object> testInstance = context.getTestInstance();
67
68 if (testInstance.isPresent()
69 && testInstance.get() instanceof WebDriverTestCase) {
70 final WebDriverTestCase webDriverTestCase = (WebDriverTestCase) testInstance.get();
71 if (!webDriverTestCase.useRealBrowser()) {
72 verifyNoOutput();
73 }
74 }
75 else {
76 verifyNoOutput();
77 }
78 }
79 finally {
80 restoreSystemErr();
81 }
82 }
83
84 void verifyNoOutput() {
85 if (baos_.size() != 0) {
86 String output = baos_.toString();
87
88
89 for (final Pattern pattern : PATTERNS) {
90 output = pattern.matcher(output).replaceAll("");
91 }
92
93 if (!output.isEmpty()) {
94 if (output.contains("ChromeDriver")) {
95 throw new RuntimeException("Outdated Chrome driver version: " + output);
96 }
97 if (output.contains("geckodriver")) {
98 throw new RuntimeException("Outdated Gecko driver version: " + output);
99 }
100 output = StringUtils.replaceEach(output, new String[] {"\n", "\r"}, new String[]{"\\n", "\\r"});
101 throw new RuntimeException("Test has produced output to System.err: " + output);
102 }
103 }
104 }
105
106 private void wrapSystemErr() {
107 originalErr_ = System.err;
108 System.setErr(new NSAPrintStreamWrapper(originalErr_, baos_));
109 }
110
111 void restoreSystemErr() {
112 System.setErr(originalErr_);
113 }
114 }
115
116
117
118
119
120 class NSAPrintStreamWrapper extends PrintStream {
121 private PrintStream wrapped_;
122
123 NSAPrintStreamWrapper(final PrintStream original, final OutputStream spyOut) {
124 super(spyOut, true);
125 wrapped_ = original;
126 }
127
128
129
130
131 @Override
132 public int hashCode() {
133 return wrapped_.hashCode();
134 }
135
136
137
138
139 @Override
140 public boolean equals(final Object obj) {
141 return wrapped_.equals(obj);
142 }
143
144
145
146
147 @Override
148 public String toString() {
149 return wrapped_.toString();
150 }
151
152
153
154
155 @Override
156 public void flush() {
157 super.flush();
158 wrapped_.flush();
159 }
160
161
162
163
164 @Override
165 public void close() {
166 super.close();
167 wrapped_.close();
168 }
169
170
171
172
173 @Override
174 public boolean checkError() {
175 super.checkError();
176 return wrapped_.checkError();
177 }
178
179
180
181
182 @Override
183 public void write(final int b) {
184 super.write(b);
185 wrapped_.write(b);
186 }
187
188
189
190
191 @Override
192 public void write(final byte[] buf, final int off, final int len) {
193 super.write(buf, off, len);
194 wrapped_.write(buf, off, len);
195 }
196 }