From e7d870a7fa0c16c7f66c1cb3d85a936a7569ea70 Mon Sep 17 00:00:00 2001 From: Darin Kelkhoff Date: Mon, 29 Apr 2024 12:52:29 -0500 Subject: [PATCH] CE-1068 - Add dumping console logs upon error - could help diagnose test fails faster hopefully --- .../selenium/lib/QBaseSeleniumTest.java | 12 +- .../selenium/lib/QSeleniumLib.java | 20 +++ .../selenium/lib/SeleniumTestWatcher.java | 126 ++++++++++++++++++ 3 files changed, 154 insertions(+), 4 deletions(-) create mode 100644 src/test/java/com/kingsrook/qqq/frontend/materialdashboard/selenium/lib/SeleniumTestWatcher.java diff --git a/src/test/java/com/kingsrook/qqq/frontend/materialdashboard/selenium/lib/QBaseSeleniumTest.java b/src/test/java/com/kingsrook/qqq/frontend/materialdashboard/selenium/lib/QBaseSeleniumTest.java index 57ed9c1..5d6e058 100755 --- a/src/test/java/com/kingsrook/qqq/frontend/materialdashboard/selenium/lib/QBaseSeleniumTest.java +++ b/src/test/java/com/kingsrook/qqq/frontend/materialdashboard/selenium/lib/QBaseSeleniumTest.java @@ -33,6 +33,7 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.TestInfo; +import org.junit.jupiter.api.extension.ExtendWith; import org.openqa.selenium.Dimension; import org.openqa.selenium.WebDriver; import org.openqa.selenium.chrome.ChromeDriver; @@ -43,6 +44,7 @@ import static org.junit.jupiter.api.Assertions.fail; /******************************************************************************* ** Base class for Selenium tests *******************************************************************************/ +@ExtendWith(SeleniumTestWatcher.class) public class QBaseSeleniumTest { protected static ChromeOptions chromeOptions; @@ -93,6 +95,8 @@ public class QBaseSeleniumTest driver.manage().window().setSize(new Dimension(1700, 1300)); qSeleniumLib = new QSeleniumLib(driver); + SeleniumTestWatcher.setCurrentSeleniumLib(qSeleniumLib); + if(useInternalJavalin()) { qSeleniumJavalin = new QSeleniumJavalin(); @@ -197,10 +201,10 @@ public class QBaseSeleniumTest qSeleniumLib.takeScreenshotToFile(getClass().getSimpleName() + "/" + testInfo.getDisplayName()); } - if(driver != null) - { - driver.quit(); - } + //////////////////////////////////////////////////////////////////////////////////////// + // note - at one time we did a driver.quit here - but we're moving that into // + // SeleniumTestWatcher, so it can dump logs if it wants to (it runs after the @After) // + //////////////////////////////////////////////////////////////////////////////////////// if(qSeleniumJavalin != null) { diff --git a/src/test/java/com/kingsrook/qqq/frontend/materialdashboard/selenium/lib/QSeleniumLib.java b/src/test/java/com/kingsrook/qqq/frontend/materialdashboard/selenium/lib/QSeleniumLib.java index 18a4f98..9671353 100755 --- a/src/test/java/com/kingsrook/qqq/frontend/materialdashboard/selenium/lib/QSeleniumLib.java +++ b/src/test/java/com/kingsrook/qqq/frontend/materialdashboard/selenium/lib/QSeleniumLib.java @@ -42,6 +42,8 @@ import org.openqa.selenium.StaleElementReferenceException; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.interactions.Actions; +import org.openqa.selenium.logging.LogEntries; +import org.openqa.selenium.logging.LogEntry; import org.openqa.selenium.support.ui.ExpectedConditions; import org.openqa.selenium.support.ui.WebDriverWait; import static org.assertj.core.api.Assertions.assertThat; @@ -735,4 +737,22 @@ public class QSeleniumLib return (this); } + + + /******************************************************************************* + ** + *******************************************************************************/ + public void dumpConsole() + { + Set availableLogTypes = driver.manage().logs().getAvailableLogTypes(); + for(String logType : availableLogTypes) + { + LogEntries logEntries = driver.manage().logs().get(logType); + for(LogEntry logEntry : logEntries) + { + System.out.println(logEntry.toJson()); + } + } + } + } diff --git a/src/test/java/com/kingsrook/qqq/frontend/materialdashboard/selenium/lib/SeleniumTestWatcher.java b/src/test/java/com/kingsrook/qqq/frontend/materialdashboard/selenium/lib/SeleniumTestWatcher.java new file mode 100644 index 0000000..0aa34b5 --- /dev/null +++ b/src/test/java/com/kingsrook/qqq/frontend/materialdashboard/selenium/lib/SeleniumTestWatcher.java @@ -0,0 +1,126 @@ +/* + * QQQ - Low-code Application Framework for Engineers. + * Copyright (C) 2021-2024. Kingsrook, LLC + * 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States + * contact@kingsrook.com + * https://github.com/Kingsrook/ + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package com.kingsrook.qqq.frontend.materialdashboard.selenium.lib; + + +import java.util.Optional; +import org.junit.jupiter.api.extension.ExtensionContext; +import org.junit.jupiter.api.extension.TestWatcher; + + +/******************************************************************************* + ** + *******************************************************************************/ +public class SeleniumTestWatcher implements TestWatcher +{ + private static QSeleniumLib qSeleniumLib; + + + + /******************************************************************************* + ** + *******************************************************************************/ + public static void setCurrentSeleniumLib(QSeleniumLib qSeleniumLib) + { + SeleniumTestWatcher.qSeleniumLib = qSeleniumLib; + } + + + + /******************************************************************************* + ** + *******************************************************************************/ + @Override + public void testFailed(ExtensionContext context, Throwable cause) + { + if(qSeleniumLib != null) + { + System.out.println("Dumping browser console after failed test: " + context.getDisplayName()); + System.out.println("----------------------------------------------------------------------------"); + try + { + qSeleniumLib.dumpConsole(); + } + catch(Exception e) + { + System.out.println("Error dumping console:"); + e.printStackTrace(); + } + System.out.println("----------------------------------------------------------------------------"); + } + + tryToQuitSelenium(); + } + + + + /******************************************************************************* + ** + *******************************************************************************/ + private void tryToQuitSelenium() + { + if(qSeleniumLib != null) + { + try + { + qSeleniumLib.driver.quit(); + } + catch(Exception e) + { + System.err.println("Error quiting selenium driver: " + e.getMessage()); + } + } + } + + + + /******************************************************************************* + ** + *******************************************************************************/ + @Override + public void testSuccessful(ExtensionContext context) + { + tryToQuitSelenium(); + } + + + + /******************************************************************************* + ** + *******************************************************************************/ + @Override + public void testAborted(ExtensionContext context, Throwable cause) + { + tryToQuitSelenium(); + } + + + + /******************************************************************************* + ** + *******************************************************************************/ + @Override + public void testDisabled(ExtensionContext context, Optional reason) + { + tryToQuitSelenium(); + } +}