1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package org.htmlunit.source;
16
17 import static java.nio.charset.StandardCharsets.ISO_8859_1;
18
19 import java.io.BufferedReader;
20 import java.io.BufferedWriter;
21 import java.io.File;
22 import java.io.FileReader;
23 import java.io.FileWriter;
24 import java.io.IOException;
25 import java.util.ArrayList;
26 import java.util.Collection;
27 import java.util.Collections;
28 import java.util.HashMap;
29 import java.util.HashSet;
30 import java.util.Iterator;
31 import java.util.List;
32 import java.util.Map;
33 import java.util.TreeMap;
34 import java.util.TreeSet;
35 import java.util.regex.Matcher;
36 import java.util.regex.Pattern;
37
38 import org.apache.commons.io.FileUtils;
39 import org.apache.commons.lang3.reflect.MethodUtils;
40 import org.htmlunit.WebDriverTestCase;
41 import org.htmlunit.junit.annotation.TestedBrowser;
42 import org.htmlunit.libraries.JQuery3x3x1Test;
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60 public final class JQueryExtractor {
61 private static final String RERUN_ID = "Rerun [";
62
63 private JQueryExtractor() {
64 }
65
66
67
68
69
70
71 public static void main(final String[] args) throws Exception {
72
73
74
75 final Class<? extends WebDriverTestCase> testClass = JQuery3x3x1Test.class;
76
77 final String version = (String) MethodUtils.invokeExactMethod(testClass.newInstance(), "getVersion");
78 final File baseDir = new File("src/test/resources/libraries/jQuery/" + version + "/expectations");
79
80 for (final String browser : new String[] {"CHROME", "EDGE", "FF", "FF-ESR"}) {
81 final File out = new File(baseDir, browser + ".out");
82 final File results = new File(baseDir, "results." + browser + ".txt");
83 extractExpectations(out, results);
84 }
85
86 generateTestCases(testClass, baseDir);
87 }
88
89
90
91
92
93
94
95
96
97 public static void extractExpectations(final File input, final File output) throws IOException {
98 try (BufferedReader reader = new BufferedReader(new FileReader(input))) {
99 try (BufferedWriter writer = new BufferedWriter(new FileWriter(output))) {
100 int testNumber = 1;
101 String line;
102 while ((line = reader.readLine()) != null) {
103 line = line.trim();
104
105
106
107 if (line.contains(RERUN_ID)) {
108 final int start = line.indexOf(RERUN_ID) + RERUN_ID.length();
109 final int end = line.indexOf(']', start);
110 final String testId = line.substring(start, end);
111
112 line = line.substring(0, line.indexOf(RERUN_ID)).trim();
113 final String prefix = "" + testNumber + ".";
114 if (line.startsWith(prefix)) {
115 line = line.substring(prefix.length());
116 }
117 line = "" + testNumber + '.' + ' ' + line + " [" + testId + ']';
118 writer.write(line + System.lineSeparator());
119 testNumber++;
120 }
121
122
123
124
125 else if (line.indexOf("Rerun") > -1) {
126 line = line.substring(0, line.indexOf("Rerun"))
127 + " [" + testNumber + ']';
128 writer.write(line + System.lineSeparator());
129 testNumber++;
130 }
131 else if (line.endsWith("Rerun")) {
132 if (line.indexOf("" + testNumber + '.', 4) != -1) {
133 System.out.println("Incorrect line for test# " + testNumber
134 + ", please correct it manually");
135 break;
136 }
137 line = "" + testNumber + '.'
138 + ' ' + line.substring(0, line.length() - 5)
139 + " [" + testNumber + ']';
140 writer.write(line + System.lineSeparator());
141 testNumber++;
142 }
143 }
144 System.out.println("Last output #" + (testNumber - 1));
145 }
146 }
147 }
148
149
150
151
152
153
154
155 public static void generateTestCases(final Class<? extends WebDriverTestCase> testClass,
156 final File dir) throws Exception {
157 final TestedBrowser[] browsers = TestedBrowser.values();
158
159 final List<String> mainNames = new ArrayList<>();
160 for (final TestedBrowser b : browsers) {
161 String name = b.name();
162 if ("FF_ESR".equals(name)) {
163 name = "FF-ESR";
164 }
165 mainNames.add(name);
166 }
167
168 final Map<String, Expectations> browserExpectations = new HashMap<>();
169 final File[] files = dir.listFiles();
170 if (files != null) {
171 for (final File file : files) {
172 if (file.isFile() && file.getName().endsWith(".txt")) {
173 for (final String browserName : mainNames) {
174 if (file.getName().equalsIgnoreCase("results." + browserName + ".txt")) {
175 browserExpectations.put(browserName, Expectations.readExpectations(file));
176 }
177 }
178 }
179 }
180 }
181
182
183 final List<Test> allTests = computeTestsList(browserExpectations);
184
185 final Collection<String> availableBrowserNames = new TreeSet<>(browserExpectations.keySet());
186 for (final Test test : allTests) {
187 final Map<String, String> testExpectation = new TreeMap<>();
188 final Map<Integer, List<String>> lineToBrowser = new TreeMap<>();
189 for (final String browserName : availableBrowserNames) {
190 final Expectation expectation = browserExpectations.get(browserName).getExpectation(test);
191 if (expectation != null) {
192 List<String> browsersForLine = lineToBrowser.get(expectation.getLine());
193 if (browsersForLine == null) {
194 browsersForLine = new ArrayList<>();
195 lineToBrowser.put(expectation.getLine(), browsersForLine);
196 }
197 browsersForLine.add(browserName);
198 final String str = expectation.getTestResult();
199 testExpectation.put(browserName,
200 str.replaceAll("\\\\", "\\\\\\\\").replaceAll("\\\"", "\\\\\""));
201 }
202 }
203 System.out.println(" /**");
204 System.out.println(" * Test " + lineToBrowser + ".");
205 System.out.println(" * @throws Exception if an error occurs");
206 System.out.println(" */");
207 System.out.println(" @Test");
208 System.out.print(" @Alerts(");
209
210 final boolean allSame = testExpectation.size() == availableBrowserNames.size()
211 && new HashSet<>(testExpectation.values()).size() == 1;
212 if (allSame) {
213 final String first = testExpectation.keySet().iterator().next();
214 String expectation = testExpectation.get(first);
215 if (expectation.length() > 100) {
216 expectation = expectation.substring(0, 50) + "\"\n + \"" + expectation.substring(50);
217 }
218 System.out.print("\"" + expectation + '"');
219 }
220 else {
221 final List<String> cleanedBrowserNames = new ArrayList<>(testExpectation.keySet());
222 Collections.sort(cleanedBrowserNames);
223
224 if (testExpectation.size() == availableBrowserNames.size()) {
225
226
227 int matches = 0;
228 ArrayList<String> defaultBrowsers = null;
229
230 for (final String browser : cleanedBrowserNames) {
231 final String expectation = testExpectation.get(browser);
232
233 final ArrayList<String> matchBrowsers = new ArrayList<>();
234 int matchCount = 0;
235 for (final String otherBrowser : cleanedBrowserNames) {
236 if (!browser.equals(otherBrowser)
237 && expectation.equals(testExpectation.get(otherBrowser))) {
238 matchCount++;
239 matchBrowsers.add(otherBrowser);
240 }
241 }
242 if (matches < matchCount) {
243 matches = matchCount;
244 matchBrowsers.add(browser);
245 defaultBrowsers = matchBrowsers;
246 }
247 }
248
249 if (matches > 1) {
250 testExpectation.put("DEFAULT", testExpectation.get(defaultBrowsers.get(0)));
251 cleanedBrowserNames.add(0, "DEFAULT");
252 for (final String browser : defaultBrowsers) {
253 testExpectation.remove(browser);
254 cleanedBrowserNames.remove(browser);
255 }
256 }
257 }
258
259 boolean first = true;
260 if (cleanedBrowserNames.size() == 1 && "DEFAULT".equals(cleanedBrowserNames.get(0))) {
261 System.out.print("\"" + testExpectation.get("DEFAULT") + '"');
262 }
263 else {
264 for (final String browserName : cleanedBrowserNames) {
265 final String expectation = testExpectation.get(browserName);
266 if (expectation == null) {
267 continue;
268 }
269 if (!first) {
270 System.out.println(",");
271 System.out.print(" ");
272 }
273 System.out.print(browserName + " = \"" + expectation + '"');
274 first = false;
275 }
276 }
277 }
278 System.out.println(")");
279
280 final String methodName = test.getName().replaceAll("\\W", "_");
281
282 System.out.println(" public void " + methodName + "() throws Exception {");
283 System.out.println(" runTest(\"" + test.getName().replace("\"", "\\\"") + "\");");
284 System.out.println(" }");
285 System.out.println();
286 }
287 }
288
289 private static List<Test> computeTestsList(final Map<String, Expectations> browserExpectations) {
290 final Map<String, Test> map = new HashMap<>();
291 for (final Expectations expectations : browserExpectations.values()) {
292 for (final Expectation expectation : expectations) {
293 final String testName = expectation.getTestName();
294 if (!testName.startsWith("skipped")) {
295 Test test = map.get(testName);
296 if (test == null) {
297 test = new Test(testName);
298 map.put(testName, test);
299 }
300 test.addLine(expectation.getLine());
301 }
302 }
303 }
304
305 final List<Test> tests = new ArrayList<>(map.values());
306 Collections.sort(tests);
307
308 return tests;
309 }
310
311 static class Expectations implements Iterable<Expectation> {
312 static Expectations readExpectations(final File file) throws IOException {
313 final Expectations expectations = new Expectations();
314 final List<String> lines = FileUtils.readLines(file, ISO_8859_1);
315 for (int i = 0; i < lines.size(); i++) {
316 expectations.add(new Expectation(file, i + 1, lines.get(i)));
317 }
318
319 return expectations;
320 }
321
322 private final Map<String, Expectation> expectations_ = new HashMap<>();
323
324 public Expectation getExpectation(final Test test) {
325 return expectations_.get(test.getName());
326 }
327
328 private void add(final Expectation expectation) {
329 expectations_.put(expectation.getTestName(), expectation);
330 }
331
332 @Override
333 public Iterator<Expectation> iterator() {
334 return expectations_.values().iterator();
335 }
336 }
337
338 static class Expectation {
339
340 private static final Pattern PATTERN =
341 Pattern.compile("(\\d+\\. ?)?(.+)\\((\\d+(, \\d+, \\d+)?)\\) \\[([0-9a-f]{1,8})\\]");
342
343 private final int line_;
344 private final String testId_;
345 private final String testName_;
346 private final String testResult_;
347
348 Expectation(final File file, final int line, final String string) {
349 line_ = line;
350 final Matcher matcher = PATTERN.matcher(string);
351 if (!matcher.matches()) {
352 throw new RuntimeException("Invalid line " + line + ": '" + string
353 + "' in file: " + file.getAbsolutePath());
354 }
355 final String testNumber = matcher.group(1);
356 if (testNumber != null && !testNumber.trim().equals(line + ".")) {
357 throw new RuntimeException("Invalid test number for line " + line + ": " + string
358 + " in file: " + file.getAbsolutePath());
359 }
360
361 testName_ = matcher.group(2).trim();
362 testResult_ = matcher.group(3);
363 testId_ = matcher.group(4);
364 }
365
366 public int getLine() {
367 return line_;
368 }
369
370 public String getTestId() {
371 return testId_;
372 }
373
374 public String getTestName() {
375 return testName_;
376 }
377
378 public String getTestResult() {
379 return testResult_;
380 }
381 }
382
383 static class Test implements Comparable<Test> {
384 private final List<Integer> lines_ = new ArrayList<>();
385 private final String name_;
386
387 Test(final String name) {
388 name_ = name;
389 }
390
391 public String getName() {
392 return name_;
393 }
394
395 void addLine(final int line) {
396 if (!lines_.contains(line)) {
397 lines_.add(line);
398 Collections.sort(lines_);
399 }
400 }
401
402 @Override
403 public int compareTo(final Test o) {
404 int diff = lines_.get(0) - o.lines_.get(0);
405 if (diff == 0) {
406 diff = lines_.size() - o.lines_.size();
407 if (diff == 0) {
408 diff = name_.compareTo(o.name_);
409 }
410 }
411 return diff;
412 }
413
414 @Override
415 public int hashCode() {
416 return name_.hashCode();
417 }
418
419 @Override
420 public boolean equals(final Object obj) {
421 return (obj instanceof Test) && name_.equals(((Test) obj).name_);
422 }
423 }
424 }