From dba58a491bea42f8e97aab94626adb3ec55a8628 Mon Sep 17 00:00:00 2001 From: labkey-tchad Date: Fri, 29 Jul 2022 14:58:01 -0700 Subject: [PATCH 01/11] Capture browser logs --- src/org/labkey/test/TestProperties.java | 5 +++ src/org/labkey/test/WebDriverWrapper.java | 40 +++++++++++++++++++++-- 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/src/org/labkey/test/TestProperties.java b/src/org/labkey/test/TestProperties.java index 7e3e614958..1c78e17711 100644 --- a/src/org/labkey/test/TestProperties.java +++ b/src/org/labkey/test/TestProperties.java @@ -192,6 +192,11 @@ public static boolean isDebugLoggingEnabled() return "true".equals(System.getProperty("webtest.logging.debug")); } + public static boolean isConsoleLogEnabled() + { + return "true".equals(System.getProperty("webtest.devtools.console.log")); + } + public static boolean isPrimaryUserAppAdmin() { return "true".equals(System.getProperty("webtest.primary.app.admin")); diff --git a/src/org/labkey/test/WebDriverWrapper.java b/src/org/labkey/test/WebDriverWrapper.java index 5f7aa98aa7..24769e2c17 100644 --- a/src/org/labkey/test/WebDriverWrapper.java +++ b/src/org/labkey/test/WebDriverWrapper.java @@ -23,6 +23,8 @@ import org.apache.commons.lang3.mutable.MutableInt; import org.apache.commons.lang3.tuple.ImmutablePair; import org.apache.commons.lang3.tuple.Pair; +import org.apache.logging.log4j.Level; +import org.apache.logging.log4j.LogManager; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -80,6 +82,11 @@ import org.openqa.selenium.chrome.ChromeDriver; import org.openqa.selenium.chrome.ChromeDriverService; import org.openqa.selenium.chrome.ChromeOptions; +import org.openqa.selenium.devtools.DevTools; +import org.openqa.selenium.devtools.HasDevTools; +import org.openqa.selenium.devtools.v85.log.Log; +import org.openqa.selenium.devtools.v85.log.model.LogEntry; +import org.openqa.selenium.devtools.v85.runtime.model.ConsoleAPICalled; import org.openqa.selenium.firefox.FirefoxBinary; import org.openqa.selenium.firefox.FirefoxDriver; import org.openqa.selenium.firefox.FirefoxDriverLogLevel; @@ -89,6 +96,7 @@ import org.openqa.selenium.firefox.GeckoDriverService; import org.openqa.selenium.ie.InternetExplorerDriver; import org.openqa.selenium.interactions.Actions; +import org.openqa.selenium.remote.Augmenter; import org.openqa.selenium.remote.RemoteWebDriver; import org.openqa.selenium.remote.service.DriverService; import org.openqa.selenium.support.ui.ExpectedConditions; @@ -131,11 +139,11 @@ import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import java.util.function.Supplier; -import java.util.logging.Level; import java.util.logging.Logger; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; +import org.openqa.selenium.devtools.v85.runtime.Runtime; import static org.apache.commons.lang3.StringUtils.trimToNull; import static org.junit.Assert.assertEquals; @@ -171,7 +179,7 @@ public abstract class WebDriverWrapper implements WrapsDriver { // Eliminate noise from org.openqa.selenium.remote.ProtocolHandshake and org.openqa.selenium.interactions.Actions if (!isWebDriverLoggingEnabled()) - Logger.getLogger("org.openqa.selenium").setLevel(Level.WARNING); + Logger.getLogger("org.openqa.selenium").setLevel(java.util.logging.Level.WARNING); } public WebDriverWrapper() @@ -393,6 +401,12 @@ protected Pair createNewWebDriver(@NotNull Pair LOG_ENTRY_LEVELS = Map.of( + LogEntry.Level.VERBOSE, Level.DEBUG, + LogEntry.Level.INFO, Level.INFO, + LogEntry.Level.WARNING, Level.WARN, + LogEntry.Level.ERROR, Level.ERROR + ); + + static final org.apache.logging.log4j.Logger LOGGER = LogManager.getLogger(BrowserConsoleLog.class); + + static void log(LogEntry logEntry) + { + LOGGER.log(LOG_ENTRY_LEVELS.get(logEntry.getLevel()), logEntry.getText()); + } +} From da09a4d164308256ad847d1b16269d821bfb9de0 Mon Sep 17 00:00:00 2001 From: labkey-tchad Date: Mon, 1 Aug 2022 10:50:30 -0700 Subject: [PATCH 02/11] Include log source --- src/org/labkey/test/WebDriverWrapper.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/org/labkey/test/WebDriverWrapper.java b/src/org/labkey/test/WebDriverWrapper.java index 24769e2c17..45aff94eb9 100644 --- a/src/org/labkey/test/WebDriverWrapper.java +++ b/src/org/labkey/test/WebDriverWrapper.java @@ -3955,6 +3955,7 @@ class BrowserConsoleLog static void log(LogEntry logEntry) { - LOGGER.log(LOG_ENTRY_LEVELS.get(logEntry.getLevel()), logEntry.getText()); + String msgPrefix = logEntry.getSource() == null ? "" : "[" + logEntry.getSource() + "] "; + LOGGER.log(LOG_ENTRY_LEVELS.get(logEntry.getLevel()), msgPrefix + logEntry.getText()); } } From db40ff00387c070ba06075dad9d674596db217a8 Mon Sep 17 00:00:00 2001 From: labkey-tchad Date: Mon, 1 Aug 2022 10:51:49 -0700 Subject: [PATCH 03/11] source can't be null --- src/org/labkey/test/WebDriverWrapper.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/org/labkey/test/WebDriverWrapper.java b/src/org/labkey/test/WebDriverWrapper.java index 45aff94eb9..988fc24ce2 100644 --- a/src/org/labkey/test/WebDriverWrapper.java +++ b/src/org/labkey/test/WebDriverWrapper.java @@ -3955,7 +3955,6 @@ class BrowserConsoleLog static void log(LogEntry logEntry) { - String msgPrefix = logEntry.getSource() == null ? "" : "[" + logEntry.getSource() + "] "; - LOGGER.log(LOG_ENTRY_LEVELS.get(logEntry.getLevel()), msgPrefix + logEntry.getText()); + LOGGER.log(LOG_ENTRY_LEVELS.get(logEntry.getLevel()), "[" + logEntry.getSource() + "] " + logEntry.getText()); } } From 21f3c678bae1c89291a47821c6a6a067b456ff99 Mon Sep 17 00:00:00 2001 From: labkey-tchad Date: Mon, 1 Aug 2022 12:38:32 -0700 Subject: [PATCH 04/11] Catch DevToolsException --- src/org/labkey/test/WebDriverWrapper.java | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/org/labkey/test/WebDriverWrapper.java b/src/org/labkey/test/WebDriverWrapper.java index 988fc24ce2..2508a07b23 100644 --- a/src/org/labkey/test/WebDriverWrapper.java +++ b/src/org/labkey/test/WebDriverWrapper.java @@ -83,10 +83,10 @@ import org.openqa.selenium.chrome.ChromeDriverService; import org.openqa.selenium.chrome.ChromeOptions; import org.openqa.selenium.devtools.DevTools; +import org.openqa.selenium.devtools.DevToolsException; import org.openqa.selenium.devtools.HasDevTools; import org.openqa.selenium.devtools.v85.log.Log; import org.openqa.selenium.devtools.v85.log.model.LogEntry; -import org.openqa.selenium.devtools.v85.runtime.model.ConsoleAPICalled; import org.openqa.selenium.firefox.FirefoxBinary; import org.openqa.selenium.firefox.FirefoxDriver; import org.openqa.selenium.firefox.FirefoxDriverLogLevel; @@ -143,7 +143,6 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; -import org.openqa.selenium.devtools.v85.runtime.Runtime; import static org.apache.commons.lang3.StringUtils.trimToNull; import static org.junit.Assert.assertEquals; @@ -401,11 +400,18 @@ protected Pair createNewWebDriver(@NotNull Pair Date: Mon, 1 Aug 2022 14:42:07 -0700 Subject: [PATCH 05/11] Use bidi log collection --- src/org/labkey/test/WebDriverWrapper.java | 76 ++++++++++++----------- 1 file changed, 40 insertions(+), 36 deletions(-) diff --git a/src/org/labkey/test/WebDriverWrapper.java b/src/org/labkey/test/WebDriverWrapper.java index 2508a07b23..452ae7f288 100644 --- a/src/org/labkey/test/WebDriverWrapper.java +++ b/src/org/labkey/test/WebDriverWrapper.java @@ -79,14 +79,14 @@ import org.openqa.selenium.WebDriverException; import org.openqa.selenium.WebElement; import org.openqa.selenium.WrapsDriver; +import org.openqa.selenium.bidi.BiDi; +import org.openqa.selenium.bidi.log.BaseLogEntry; +import org.openqa.selenium.bidi.log.GenericLogEntry; +import org.openqa.selenium.bidi.log.Log; +import org.openqa.selenium.bidi.log.LogEntry; import org.openqa.selenium.chrome.ChromeDriver; import org.openqa.selenium.chrome.ChromeDriverService; import org.openqa.selenium.chrome.ChromeOptions; -import org.openqa.selenium.devtools.DevTools; -import org.openqa.selenium.devtools.DevToolsException; -import org.openqa.selenium.devtools.HasDevTools; -import org.openqa.selenium.devtools.v85.log.Log; -import org.openqa.selenium.devtools.v85.log.model.LogEntry; import org.openqa.selenium.firefox.FirefoxBinary; import org.openqa.selenium.firefox.FirefoxDriver; import org.openqa.selenium.firefox.FirefoxDriverLogLevel; @@ -344,10 +344,11 @@ protected Pair createNewWebDriver(@NotNull Pair createNewWebDriver(@NotNull Pair createNewWebDriver(@NotNull Pair createNewWebDriver(@NotNull Pair LOG_ENTRY_LEVELS = Map.of( - LogEntry.Level.VERBOSE, Level.DEBUG, - LogEntry.Level.INFO, Level.INFO, - LogEntry.Level.WARNING, Level.WARN, - LogEntry.Level.ERROR, Level.ERROR + // TODO: BaseLogEntry.LogLevel isn't public + private static final Map LOG_ENTRY_LEVELS = Map.of( + "debug", Level.DEBUG, + "info", Level.INFO, + "warning", Level.WARN, + "error", Level.ERROR ); static final org.apache.logging.log4j.Logger LOGGER = LogManager.getLogger(BrowserConsoleLog.class); - static void log(LogEntry logEntry) + static void log(LogEntry bidiLogEntry) + { + if (bidiLogEntry.getConsoleLogEntry().isPresent()) + { + log(bidiLogEntry.getConsoleLogEntry().get()); + } + else if (bidiLogEntry.getGenericLogEntry().isPresent()) + { + log(bidiLogEntry.getGenericLogEntry().get()); + } + else if (bidiLogEntry.getJavascriptLogEntry().isPresent()) + { + log(bidiLogEntry.getJavascriptLogEntry().get()); + } + } + + static void log(GenericLogEntry logEntry) { - LOGGER.log(LOG_ENTRY_LEVELS.get(logEntry.getLevel()), "[" + logEntry.getSource() + "] " + logEntry.getText()); + String type = logEntry.getType(); + String prefix = type != null ? "[" + type + "] " : ""; + Level logLevel = LOG_ENTRY_LEVELS.get(String.valueOf(logEntry.getLevel())); + LOGGER.log(logLevel == null ? Level.INFO : logLevel, prefix + logEntry.getText()); } } From a9a358a77f906e004b262598e9d01bff235b573b Mon Sep 17 00:00:00 2001 From: labkey-tchad Date: Thu, 11 Aug 2022 14:36:53 -0700 Subject: [PATCH 06/11] Upgrade Selenium --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index f6b9907b01..a22e8ec876 100644 --- a/gradle.properties +++ b/gradle.properties @@ -5,7 +5,7 @@ hamcrestCoreVersion=1.3 lookfirstSardineVersion=5.7 jettyRepackagedVersion=9.4.12.v20180830 -seleniumVersion=4.1.4 +seleniumVersion=4.4.0 mockserverNettyVersion=5.5.1 labkeySchemasTestVersion=22.3-SNAPSHOT From 959f00db5a1879c6a4f5cf2f6bfefb715ba8a59f Mon Sep 17 00:00:00 2001 From: labkey-tchad Date: Mon, 20 May 2024 11:57:43 -0700 Subject: [PATCH 07/11] Update --- src/org/labkey/test/WebDriverWrapper.java | 25 ++++++----------------- 1 file changed, 6 insertions(+), 19 deletions(-) diff --git a/src/org/labkey/test/WebDriverWrapper.java b/src/org/labkey/test/WebDriverWrapper.java index 9ce3a15264..74ae39583a 100644 --- a/src/org/labkey/test/WebDriverWrapper.java +++ b/src/org/labkey/test/WebDriverWrapper.java @@ -83,14 +83,12 @@ import org.openqa.selenium.WebElement; import org.openqa.selenium.WrapsDriver; import org.openqa.selenium.bidi.BiDi; -import org.openqa.selenium.bidi.log.BaseLogEntry; import org.openqa.selenium.bidi.log.GenericLogEntry; import org.openqa.selenium.bidi.log.Log; import org.openqa.selenium.bidi.log.LogEntry; import org.openqa.selenium.chrome.ChromeDriver; import org.openqa.selenium.chrome.ChromeDriverService; import org.openqa.selenium.chrome.ChromeOptions; -import org.openqa.selenium.firefox.FirefoxBinary; import org.openqa.selenium.firefox.FirefoxDriver; import org.openqa.selenium.firefox.FirefoxDriverLogLevel; import org.openqa.selenium.firefox.FirefoxDriverService; @@ -99,7 +97,6 @@ import org.openqa.selenium.firefox.GeckoDriverService; import org.openqa.selenium.ie.InternetExplorerDriver; import org.openqa.selenium.interactions.Actions; -import org.openqa.selenium.remote.Augmenter; import org.openqa.selenium.remote.RemoteWebDriver; import org.openqa.selenium.remote.service.DriverService; import org.openqa.selenium.support.ui.ExpectedConditions; @@ -354,24 +351,14 @@ protected Pair createNewWebDriver(@NotNull Pair 0) - { - binary = new FirefoxBinary(new File(browserPath)); - } - else - { - binary = new FirefoxBinary(); - } - if (TestProperties.isRunWebDriverHeadless()) { TestLogger.warn("Launching Firefox in headless mode. This is still experimental"); - binary.addCommandLineOptions("--headless"); + firefoxOptions.addArguments("--headless"); } - firefoxOptions.setBinary(binary); + + String browserPath = System.getProperty("selenium.firefox.binary", ""); + firefoxOptions.setBinary(browserPath); newDriverService = GeckoDriverService.createDefaultService(); try @@ -4078,7 +4065,7 @@ static void log(GenericLogEntry logEntry) { String type = logEntry.getType(); String prefix = type != null ? "[" + type + "] " : ""; - Level logLevel = LOG_ENTRY_LEVELS.get(String.valueOf(logEntry.getLevel())); - LOGGER.log(logLevel == null ? Level.INFO : logLevel, prefix + logEntry.getText()); + Level logLevel = LOG_ENTRY_LEVELS.getOrDefault(String.valueOf(logEntry.getLevel()), Level.INFO); + LOGGER.log(logLevel, prefix + logEntry.getText()); } } From 6c8a13179300c695f0db6037f6bb23040630b6be Mon Sep 17 00:00:00 2001 From: labkey-tchad Date: Mon, 20 May 2024 11:58:37 -0700 Subject: [PATCH 08/11] Remove comment --- src/org/labkey/test/WebDriverWrapper.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/org/labkey/test/WebDriverWrapper.java b/src/org/labkey/test/WebDriverWrapper.java index 74ae39583a..c3c24a681e 100644 --- a/src/org/labkey/test/WebDriverWrapper.java +++ b/src/org/labkey/test/WebDriverWrapper.java @@ -340,9 +340,6 @@ protected Pair createNewWebDriver(@NotNull Pair Date: Mon, 20 May 2024 12:03:12 -0700 Subject: [PATCH 09/11] Add example for collecting data --- src/org/labkey/test/WebDriverWrapper.java | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/org/labkey/test/WebDriverWrapper.java b/src/org/labkey/test/WebDriverWrapper.java index c3c24a681e..12246e0fa0 100644 --- a/src/org/labkey/test/WebDriverWrapper.java +++ b/src/org/labkey/test/WebDriverWrapper.java @@ -83,9 +83,11 @@ import org.openqa.selenium.WebElement; import org.openqa.selenium.WrapsDriver; import org.openqa.selenium.bidi.BiDi; +import org.openqa.selenium.bidi.Network; import org.openqa.selenium.bidi.log.GenericLogEntry; import org.openqa.selenium.bidi.log.Log; import org.openqa.selenium.bidi.log.LogEntry; +import org.openqa.selenium.bidi.network.ResponseDetails; import org.openqa.selenium.chrome.ChromeDriver; import org.openqa.selenium.chrome.ChromeDriverService; import org.openqa.selenium.chrome.ChromeOptions; @@ -133,6 +135,7 @@ import java.util.Stack; import java.util.WeakHashMap; import java.util.concurrent.Callable; +import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -4028,6 +4031,23 @@ public void clearTooltips() if (isElementPresent(headerLoc)) mouseOver(headerLoc); } + + void doAndMeasureRequests(Runnable runnable) + { + try (Network network = new Network(getDriver())) { + List future = new CopyOnWriteArrayList<>(); + network.onResponseCompleted(future::add); + + runnable.run(); + sleep(10_000); + ResponseDetails response = future.get(0); + String windowHandle = getDriver().getWindowHandle(); + + Assert.assertEquals(windowHandle, response.getBrowsingContextId()); + Assert.assertEquals("get", response.getRequest().getMethod().toLowerCase()); + Assert.assertEquals(200L, response.getResponseData().getStatus()); + } + } } class BrowserConsoleLog From ae26b61303fe12da36ab0c1c7a524c959720a463 Mon Sep 17 00:00:00 2001 From: labkey-tchad Date: Mon, 20 May 2024 17:19:45 -0700 Subject: [PATCH 10/11] Don't abandon remote webdriver instance --- src/org/labkey/test/WebDriverWrapper.java | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/org/labkey/test/WebDriverWrapper.java b/src/org/labkey/test/WebDriverWrapper.java index 12246e0fa0..f73056c989 100644 --- a/src/org/labkey/test/WebDriverWrapper.java +++ b/src/org/labkey/test/WebDriverWrapper.java @@ -217,13 +217,16 @@ protected Pair createNewWebDriver(@NotNull Pair Date: Wed, 22 May 2024 08:22:36 -0700 Subject: [PATCH 11/11] Add method to collect request perf --- src/org/labkey/test/WebDriverWrapper.java | 48 +++++++++++++++++++---- 1 file changed, 40 insertions(+), 8 deletions(-) diff --git a/src/org/labkey/test/WebDriverWrapper.java b/src/org/labkey/test/WebDriverWrapper.java index f73056c989..55fc0a2ee4 100644 --- a/src/org/labkey/test/WebDriverWrapper.java +++ b/src/org/labkey/test/WebDriverWrapper.java @@ -83,10 +83,13 @@ import org.openqa.selenium.WebElement; import org.openqa.selenium.WrapsDriver; import org.openqa.selenium.bidi.BiDi; +import org.openqa.selenium.bidi.HasBiDi; import org.openqa.selenium.bidi.Network; import org.openqa.selenium.bidi.log.GenericLogEntry; import org.openqa.selenium.bidi.log.Log; import org.openqa.selenium.bidi.log.LogEntry; +import org.openqa.selenium.bidi.network.BaseParameters; +import org.openqa.selenium.bidi.network.BeforeRequestSent; import org.openqa.selenium.bidi.network.ResponseDetails; import org.openqa.selenium.chrome.ChromeDriver; import org.openqa.selenium.chrome.ChromeDriverService; @@ -135,7 +138,7 @@ import java.util.Stack; import java.util.WeakHashMap; import java.util.concurrent.Callable; -import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -386,8 +389,6 @@ protected Pair createNewWebDriver(@NotNull Pair createNewWebDriver(@NotNull Pair future = new CopyOnWriteArrayList<>(); - network.onResponseCompleted(future::add); + Map requests = new ConcurrentHashMap<>(); + Map responses = new ConcurrentHashMap<>(); + network.onBeforeRequestSent(brs -> maybeAdd(requests, brs)); + network.onResponseCompleted(rd -> maybeAdd(responses, rd)); runnable.run(); - sleep(10_000); - ResponseDetails response = future.get(0); + + sleep(1_000); + waitFor(() -> requests.size() == responses.size(), timeoutMs); + ResponseDetails response = responses.get(0); + String windowHandle = getDriver().getWindowHandle(); Assert.assertEquals(windowHandle, response.getBrowsingContextId()); @@ -4051,6 +4068,21 @@ void doAndMeasureRequests(Runnable runnable) Assert.assertEquals(200L, response.getResponseData().getStatus()); } } + + private static final Pattern actionPattern = Pattern.compile("\\.(view|api)(\\?|$)"); + private static void maybeAdd(Map list, T candidate) + { + String requestUrl = candidate.getRequest().getUrl(); + String requestId = candidate.getRequest().getRequestId(); + if (actionPattern.matcher(requestUrl).find()) + { + list.put(requestId, candidate); + } + else + { + TestLogger.warn("Ignoring request " + requestId + ": " + requestUrl); + } + } } class BrowserConsoleLog