View Javadoc
1   /*
2    * Copyright (c) 2002-2025 Gargoyle Software Inc.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * https://www.apache.org/licenses/LICENSE-2.0
8    *
9    * Unless required by applicable law or agreed to in writing, software
10   * distributed under the License is distributed on an "AS IS" BASIS,
11   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12   * See the License for the specific language governing permissions and
13   * limitations under the License.
14   */
15  package org.htmlunit.libraries.htmx;
16  
17  import java.util.List;
18  
19  import org.htmlunit.Page;
20  import org.htmlunit.WebClient;
21  import org.htmlunit.WebDriverTestCase;
22  import org.htmlunit.html.HtmlPage;
23  import org.openqa.selenium.By;
24  import org.openqa.selenium.NoSuchElementException;
25  import org.openqa.selenium.StaleElementReferenceException;
26  import org.openqa.selenium.WebDriver;
27  import org.openqa.selenium.WebElement;
28  import org.openqa.selenium.htmlunit.HtmlUnitDriver;
29  
30  /**
31   * Tests for <a href="https://htmx.org/">htmx</a>.
32   *
33   * @author Ronald Brill
34   */
35  public abstract class HtmxTest extends WebDriverTestCase {
36  
37      private static final boolean BUG_HUNTING = false;
38  
39      private static final int RETRIES = 2;
40      private static final long RUN_TIME = 42 * DEFAULT_WAIT_TIME.toMillis();
41  
42      protected void htmx(final String subDir, final boolean min) throws Exception {
43          startWebServer("src/test/resources/libraries/htmx/" + subDir, null, null);
44  
45          try {
46              final String url = URL_FIRST + "test/index" + (min ? ".min.html" : ".html");
47              final WebDriver webDriver = getWebDriver();
48  
49              if (webDriver instanceof HtmlUnitDriver) {
50                  setupWebClient(((HtmlUnitDriver) webDriver).getWebClient());
51              }
52  
53              int tries = 0;
54              String lastStats = "";
55              webDriver.get(url);
56              long endTime = System.currentTimeMillis() + RUN_TIME;
57  
58              while (true) {
59                  lastStats = getResultElementText(webDriver);
60                  if (BUG_HUNTING && getWebDriver() instanceof HtmlUnitDriver) {
61                      System.out.println("-> " + lastStats);
62                  }
63  
64                  if (lastStats.startsWith(getExpectedAlerts()[0])) {
65                      break;
66                  }
67                  Thread.sleep(400);
68  
69                  if (System.currentTimeMillis() > endTime) {
70                      tries++;
71  
72                      if (tries < RETRIES) {
73                          lastStats = "";
74                          webDriver.get(url);
75                          endTime = System.currentTimeMillis() + RUN_TIME;
76                      }
77                      else {
78                          lastStats = "HtmxTest runs too long (longer than " + RUN_TIME / 1000 + "s) - "
79                                  + getResultElementText(webDriver);
80                          break;
81                      }
82                  }
83              }
84  
85              if (BUG_HUNTING && getWebDriver() instanceof HtmlUnitDriver) {
86                  final WebClient webClient = ((HtmlUnitDriver) getWebDriver()).getWebClient();
87  
88                  final Page page = webClient.getCurrentWindow().getEnclosedPage();
89                  System.out.println(((HtmlPage) page).asNormalizedText());
90              }
91  
92              assertTrue(lastStats + "\n\n" + getErrors(webDriver), lastStats.startsWith(getExpectedAlerts()[0]));
93          }
94          catch (final Exception e) {
95              if (BUG_HUNTING && getWebDriver() instanceof HtmlUnitDriver) {
96                  e.printStackTrace();
97                  Throwable t = e;
98                  while ((t = t.getCause()) != null) {
99                      t.printStackTrace();
100                 }
101             }
102             throw e;
103         }
104     }
105 
106     protected void setupWebClient(final WebClient webClient) {
107     }
108 
109     private static String getResultElementText(final WebDriver webdriver) {
110         // if the elem is not available or stale we return an empty string
111         // this will force a second try
112         try {
113             final WebElement elem = webdriver.findElement(By.cssSelector("#mocha-stats"));
114             try {
115                 String result = elem.getText();
116                 result = result.replaceAll("\\s", "");
117                 return result;
118             }
119             catch (final StaleElementReferenceException e) {
120                 return "";
121             }
122         }
123         catch (final NoSuchElementException e) {
124             return "";
125         }
126     }
127 
128     private static String getErrors(final WebDriver webdriver) {
129         final StringBuilder result = new StringBuilder();
130 
131         try {
132             final List<WebElement> elements = webdriver.findElements(By.tagName("li"));
133             for (final WebElement elem : elements) {
134                 final String cssClass = elem.getAttribute("class");
135                 if (cssClass != null && cssClass.contains(" fail")) {
136                     result.append(elem.getText())
137                         .append("\n-------------------------\n\n");
138                 }
139             }
140             return result.toString();
141         }
142         catch (final Exception e) {
143             return e.getMessage();
144         }
145     }
146 
147 }