diff --git a/config/neodymium.properties b/config/neodymium.properties index b579eea0..b295ef3a 100644 --- a/config/neodymium.properties +++ b/config/neodymium.properties @@ -291,6 +291,45 @@ neodymium.workInProgress = false # If false: the test data json of the corresponding test does not get attached to the allure report neodymium.report.enableTestDataInReport = true +############################# +# +# Lighthouse +# +############################# + +# Specifies the path to the Lighthouse executable +# If Lighthouse is globally installed and available in PATH, use only the name of the Lighthouse binary +# If Lighthouse is not globally installed and available in PATH, use the absolute/relative path to the Lighthouse binary +neodymium.lighthouse.binaryPath = lighthouse + +# Specifies the minimum acceptable score for the performance category in Lighthouse reports +# If the Lighthouse performance score falls below this threshold, the test will fail +# Range: 0.0 - 1.0 (representing 0% to 100%) +# The actual value for the performance score varies alot, so consider using a lower threshold to avoid a lot of false alerts +neodymium.lighthouse.assert.thresholdScore.performance = 0.5 + +# Specifies the minimum acceptable score for the accessibility category in Lighthouse reports +# If the Lighthouse accessibility score falls below this threshold, the test will fail +# Range: 0.0 - 1.0 (representing 0% to 100%) +# The actual value for the accessibility score varies alot, so consider using a lower threshold to avoid a lot of false alerts +neodymium.lighthouse.assert.thresholdScore.accessibility = 0.5 + +# Specifies the minimum acceptable score for the best practices category in Lighthouse reports +# If the Lighthouse best practices score falls below this threshold, the test will fail +# Range: 0.0 - 1.0 (representing 0% to 100%) +# The actual value for the best practices score varies alot, so consider using a lower threshold to avoid a lot of false alerts +neodymium.lighthouse.assert.thresholdScore.bestPractices = 0.5 + +# Specifies the minimum acceptable score for the seo category in Lighthouse reports +# If the Lighthouse seo score falls below this threshold, the test will fail +# Range: 0.0 - 1.0 (representing 0% to 100%) +# The actual value for the seo score varies alot, so consider using a lower threshold to avoid a lot of false alerts +neodymium.lighthouse.assert.thresholdScore.seo = 0.5 + +# To be able to validate Lighthouse report audits, we use internal json id's from the report itself +# A full list of all audit id's and their corresponding titles can be found here: https://github.com/Xceptance/neodymium/wiki/Reports#lighthouse-audit-validation +#neodymium.lighthouse.assert.audits = + ############################# # # Proxy configuration properties diff --git a/src/main/java/com/xceptance/neodymium/common/browser/BrowserRunnerHelper.java b/src/main/java/com/xceptance/neodymium/common/browser/BrowserRunnerHelper.java index 9eb1cdbc..2d0aef36 100644 --- a/src/main/java/com/xceptance/neodymium/common/browser/BrowserRunnerHelper.java +++ b/src/main/java/com/xceptance/neodymium/common/browser/BrowserRunnerHelper.java @@ -33,6 +33,7 @@ import org.openqa.selenium.firefox.GeckoDriverService.Builder; import org.openqa.selenium.ie.InternetExplorerDriver; import org.openqa.selenium.ie.InternetExplorerOptions; +import org.openqa.selenium.net.PortProber; import org.openqa.selenium.os.ExecutableFinder; import org.openqa.selenium.remote.CapabilityType; import org.openqa.selenium.remote.HttpCommandExecutor; @@ -235,6 +236,12 @@ else if (Neodymium.configuration().useProxy()) { options.addArguments("--headless"); } + + // find a free port for each chrome session (important for lighthouse) + var remoteDebuggingPort = PortProber.findFreePort(); + Neodymium.setRemoteDebuggingPort(remoteDebuggingPort); + options.addArguments("--remote-debugging-port=" + remoteDebuggingPort); + if (config.getArguments() != null && config.getArguments().size() > 0) { options.addArguments(config.getArguments()); diff --git a/src/main/java/com/xceptance/neodymium/common/recording/TakeScreenshotsThread.java b/src/main/java/com/xceptance/neodymium/common/recording/TakeScreenshotsThread.java index 9cda8546..9061aeb2 100644 --- a/src/main/java/com/xceptance/neodymium/common/recording/TakeScreenshotsThread.java +++ b/src/main/java/com/xceptance/neodymium/common/recording/TakeScreenshotsThread.java @@ -6,6 +6,7 @@ import java.lang.reflect.InvocationTargetException; import java.util.Date; +import org.openqa.selenium.NoSuchWindowException; import org.openqa.selenium.OutputType; import org.openqa.selenium.TakesScreenshot; import org.openqa.selenium.WebDriver; @@ -84,13 +85,23 @@ public synchronized void run() { long start = new Date().getTime(); - File file = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE); - writer.compressImageIfNeeded(file, recordingConfigurations.imageScaleFactor(), recordingConfigurations.imageQuality()); - long delay = recordingConfigurations.oneImagePerMilliseconds() > duration ? recordingConfigurations.oneImagePerMilliseconds() - : duration; - writer.write(file, delay); - file.delete(); - duration = new Date().getTime() - start; + + try + { + File file = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE); + writer.compressImageIfNeeded(file, recordingConfigurations.imageScaleFactor(), recordingConfigurations.imageQuality()); + long delay = recordingConfigurations.oneImagePerMilliseconds() > duration ? recordingConfigurations.oneImagePerMilliseconds() + : duration; + writer.write(file, delay); + file.delete(); + + } + catch (NoSuchWindowException e) + { + // catching the exception prevents the video from failing + } + + duration = new Date().getTime() - start; millis += duration; turns++; long sleep = recordingConfigurations.oneImagePerMilliseconds() - duration; diff --git a/src/main/java/com/xceptance/neodymium/util/LighthouseUtils.java b/src/main/java/com/xceptance/neodymium/util/LighthouseUtils.java new file mode 100644 index 00000000..da34df5c --- /dev/null +++ b/src/main/java/com/xceptance/neodymium/util/LighthouseUtils.java @@ -0,0 +1,311 @@ +package com.xceptance.neodymium.util; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.io.FileUtils; +import org.apache.commons.lang3.StringUtils; +import org.junit.Assert; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.WindowType; + +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import com.jayway.jsonpath.JsonPath; +import com.jayway.jsonpath.PathNotFoundException; + +import io.qameta.allure.Allure; + +/** + * Powered by Lighthouse (Copyright Google) + *

+ * This class is used to create Lighthouse (Copyright Google) + * reports and validate them using defined values ​​in the Neodymium configuration + *

+ */ +public class LighthouseUtils +{ + /** + * Creates a Lighthouse report + * (Copyright Google) of the current URL and adds it to the Allure report. + * + * @param reportName + * The name of the Lighthouse report attachment in the Allure report + * @throws Exception + */ + public static void createLightHouseReport(String reportName) throws Exception + { + // validate that lighthouse is installed + String readerOutput = ""; + try + { + if (System.getProperty("os.name").toLowerCase().contains("win")) + { + Process p = runProcess("cmd.exe", "/c", Neodymium.configuration().lighthouseBinaryPath(), "--version"); + checkErrorCodeProcess(p); + } + else if (System.getProperty("os.name").toLowerCase().contains("linux") || System.getProperty("os.name").toLowerCase().contains("mac")) + { + try + { + Process p = runProcess("sh", "-c", Neodymium.configuration().lighthouseBinaryPath(), "--version"); + BufferedReader r = new BufferedReader(new InputStreamReader(p.getInputStream())); + String readerLine; + while ((readerLine = r.readLine()) != null) + { + readerOutput = readerOutput + readerLine; + continue; + } + + checkErrorCodeProcess(p); + } + catch (Exception e) + { + Process p = runProcess(Neodymium.configuration().lighthouseBinaryPath(), "--version"); + checkErrorCodeProcess(p); + } + } + else + { + throw new Exception("your current operation system is not supported, please use Windows, Linux or MacOS"); + } + } + catch (Exception e) + { + throw new Exception("lighthouse binary can't be run (" + Neodymium.configuration().lighthouseBinaryPath() + + "), please install lighthouse and add it to the PATH or enter the correct lighthouse binary location.\n\nProcess Log: " + + readerOutput, e); + } + + // validate chrome browser (lighthouse only works for chrome) + SelenideAddons.wrapAssertionError(() -> { + Assert.assertTrue("the current browser is " + Neodymium.getBrowserName() + ", but lighthouse only works in combination with chrome", Neodymium.getBrowserName().contains("chrome")); + }); + + // get the current webdriver + WebDriver driver = Neodymium.getDriver(); + + // get the current URL + String URL = driver.getCurrentUrl(); + + // close window to avoid conflict with lighthouse + String newWindow = windowOperations(driver); + + // start lighthouse report + lighthouseAudit(URL, reportName); + + // add report html to allure + Allure.addAttachment(reportName, "text/html", FileUtils.openInputStream(new File("target/" + reportName + ".report.html")), "html"); + + // get report json + File jsonFile = new File("target/" + reportName + ".report.json"); + FileReader reader = new FileReader("target/" + reportName + ".report.json"); + JsonObject json = JsonParser.parseReader(reader).getAsJsonObject(); + + // get report json scores + JsonObject categories = json.getAsJsonObject("categories"); + double performanceScore = categories.getAsJsonObject("performance").get("score").getAsDouble(); + double accessibilityScore = categories.getAsJsonObject("accessibility").get("score").getAsDouble(); + double bestPracticesScore = categories.getAsJsonObject("best-practices").get("score").getAsDouble(); + double seoScore = categories.getAsJsonObject("seo").get("score").getAsDouble(); + + // validate if values in report json are greater than defined threshold in config + SelenideAddons.wrapAssertionError(() -> { + Assert.assertTrue("The Lighthouse performance score " + performanceScore + " doesn't exceed nor match the required threshold of " + Neodymium.configuration().lighthouseAssertPerformance() + ", please improve the score to match expectations and look into the corresponding Lighthouse report named \"" + reportName + "\"", Neodymium.configuration().lighthouseAssertPerformance() <= performanceScore); + Assert.assertTrue("The Lighthouse accessibility score " + accessibilityScore + " doesn't exceed nor match the required threshold of " + Neodymium.configuration().lighthouseAssertAccessibility() + ", please improve the score to match expectations and look into the corresponding Lighthouse report named \"" + reportName + "\"", Neodymium.configuration().lighthouseAssertAccessibility() <= accessibilityScore); + Assert.assertTrue("The Lighthouse best practices score " + bestPracticesScore + " doesn't exceed nor match the required threshold of " + Neodymium.configuration().lighthouseAssertBestPractices() + ", please improve the score to match expectations and look into the corresponding Lighthouse report named \"" + reportName + "\"", Neodymium.configuration().lighthouseAssertBestPractices() <= bestPracticesScore); + Assert.assertTrue("The Lighthouse seo score " + seoScore + " doesn't exceed nor match the required threshold of " + Neodymium.configuration().lighthouseAssertSeo() + ", please improve the score to match expectations and look into the corresponding Lighthouse report named \"" + reportName + "\"", Neodymium.configuration().lighthouseAssertSeo() <= seoScore); + }); + + // validate jsonpaths in neodymium properties + validateAudits(jsonFile, reportName); + + + // switch back to saved URL + driver.switchTo().window(newWindow); + driver.get(URL); + } + + /** + *

+ * Opens a new tab apart from the first tab with the test automation, adds a handle and closes the first tab. + * If the first tab with the test automation is not closed, the Lighthouse report will not have proper values, + * because it will interfere with the Lighthouse report generation. + *

+ * + * @param driver + * The current webdriver + * @return A new empty tab with a window handle + */ + private static String windowOperations(WebDriver driver) + { + String originalWindow = driver.getWindowHandle(); + driver.switchTo().newWindow(WindowType.TAB); + String newWindow = driver.getWindowHandle(); + driver.switchTo().window(originalWindow); + driver.close(); + return newWindow; + } + + /** + *

+ * Uses Lighthouse (Copyright Google) + * to create a Lighthouse report of the current URL. + *

+ * + * @param URL + * The current URL the Lighthouse report should be generated on + * @param reportName + * The name of the Lighthouse report attachment in the Allure report + * @throws Exception + */ + private static void lighthouseAudit(String URL, String reportName) throws Exception + { + Process p = null; + String readerOutput = ""; + String readerLine= ""; + + try + { + if (System.getProperty("os.name").toLowerCase().contains("win")) + { + p = runProcess("cmd.exe", "/c", Neodymium.configuration().lighthouseBinaryPath(), "--chrome-flags=\"--ignore-certificate-errors\"", URL, "--port=" + Neodymium.getRemoteDebuggingPort(), "--preset=desktop", "--output=json", "--output=html", "--output-path=target/" + reportName + ".json"); + + BufferedReader r = new BufferedReader(new InputStreamReader(p.getInputStream())); + while ((readerLine = r.readLine()) != null) + { + readerOutput = readerOutput + readerLine; + continue; + } + + checkErrorCodeProcess(p); + } + else if (System.getProperty("os.name").toLowerCase().contains("linux") || System.getProperty("os.name").toLowerCase().contains("mac")) + { + try + { + p = runProcess("sh", "-c", Neodymium.configuration().lighthouseBinaryPath(), "--chrome-flags=\"--ignore-certificate-errors\"", URL, "--port=" + Neodymium.getRemoteDebuggingPort(), "--preset=desktop", "--output=json", "--output=html", "--output-path=target/" + reportName + ".json"); + + BufferedReader r = new BufferedReader(new InputStreamReader(p.getInputStream())); + while (r.readLine() != null) + { + readerOutput = readerOutput + readerLine; + continue; + } + + checkErrorCodeProcess(p); + } + catch (Exception e) + { + p = runProcess(Neodymium.configuration().lighthouseBinaryPath(), "--chrome-flags=\"--ignore-certificate-errors\"", URL, "--port=" + Neodymium.getRemoteDebuggingPort(), "--preset=desktop", "--output=json", "--output=html", "--output-path=target/" + reportName + ".json"); + + BufferedReader r = new BufferedReader(new InputStreamReader(p.getInputStream())); + while (r.readLine() != null) + { + readerOutput = readerOutput + readerLine; + continue; + } + + checkErrorCodeProcess(p); + } + } + else + { + throw new Exception("your current operation system is not supported, please use Windows, Linux or MacOS"); + } + } + catch (IOException e) + { + throw new Exception("failed to run the lighthouse process. \n\nProcess Log: " + readerOutput, e); + } + + } + + /** + *

+ * Validates Lighthouse (Copyright Google) + * Audits specified in the Neodymium configuration. + *

+ * + * @param json + * The json file of the Lighthouse + * (Copyright Google) report + * @param reportName + * The name of the Lighthouse report attachment in the Allure report + * + * @throws Exception + */ + private static void validateAudits(File json, String reportName) throws Exception + { + String assertAuditsString = Neodymium.configuration().lighthouseAssertAudits(); + List errorAudits = new ArrayList<>(); + + if (StringUtils.isNotBlank(assertAuditsString)) + { + for (String audit : assertAuditsString.split(" ")) + { + String jsonPath = ("$.audits." + audit.trim() + ".details.items.length()"); + + try + { + int value = JsonPath.read(json, jsonPath); + + if (value > 0) + { + errorAudits.add(audit.trim()); + } + } + catch (PathNotFoundException e) + { + continue; + } + + } + + SelenideAddons.wrapAssertionError(() -> { + Assert.assertTrue("the following Lighthouse audits " + errorAudits + " contain errors that need to be fixed, please look into the Lighthouse report named \"" + reportName + "\" for further information. ", errorAudits.size() > 0); + }); + } + } + + /** + * Runs a process with the in params specified command + * + * @param + * params the command with all required parameters + * @return + * the process + * @throws IOException + */ + private static Process runProcess(String... params) throws IOException + { + ProcessBuilder builder = new ProcessBuilder(); + builder = new ProcessBuilder(params); + builder.redirectErrorStream(true); + + return builder.start(); + } + + /** + * Checks the error code for the specified process + * + * @param p + * the process of which the error code needs to be checked + * @throws InterruptedException + * @throws IOException + */ + private static void checkErrorCodeProcess(Process p) throws InterruptedException, IOException + { + int errorCode = p.waitFor(); + + if (errorCode != 0) + { + throw new IOException("process error code differs from 0"); + } + } +} diff --git a/src/main/java/com/xceptance/neodymium/util/Neodymium.java b/src/main/java/com/xceptance/neodymium/util/Neodymium.java index 43a7c698..ba8a17d1 100644 --- a/src/main/java/com/xceptance/neodymium/util/Neodymium.java +++ b/src/main/java/com/xceptance/neodymium/util/Neodymium.java @@ -36,9 +36,12 @@ public class Neodymium // keep our current browser profile name private String browserProfileName; - + // keep our current browser name private String browserName; + + // keep our current remote debugging port + private int remoteDebuggingPort; // keep last used locator private By lastLocator; @@ -265,6 +268,28 @@ public static void setBrowserName(String browserName) { getContext().browserName = browserName; } + + /** + * Remote debugging port of the current bowser + * + * @return remote debugging port + */ + public static int getRemoteDebuggingPort() + { + return getContext().remoteDebuggingPort; + } + + /** + * Set the remote debugging port of the current browser.
+ * Attention: This function is mainly used to set information within the context internally. + * + * @param remoteDebuggingPort + * the current browser port + */ + public static void setRemoteDebuggingPort(int remoteDebuggingPort) + { + getContext().remoteDebuggingPort = remoteDebuggingPort; + } /** * Current window width and height diff --git a/src/main/java/com/xceptance/neodymium/util/NeodymiumConfiguration.java b/src/main/java/com/xceptance/neodymium/util/NeodymiumConfiguration.java index fa3eb87c..3ea1688f 100644 --- a/src/main/java/com/xceptance/neodymium/util/NeodymiumConfiguration.java +++ b/src/main/java/com/xceptance/neodymium/util/NeodymiumConfiguration.java @@ -331,6 +331,29 @@ public interface NeodymiumConfiguration extends Mutable @DefaultValue("true") public boolean logNeoVersion(); + @Key("neodymium.lighthouse.binaryPath") + @DefaultValue("lighthouse") + public String lighthouseBinaryPath(); + + @Key("neodymium.lighthouse.assert.thresholdScore.performance") + @DefaultValue("0.5") + public double lighthouseAssertPerformance(); + + @Key("neodymium.lighthouse.assert.thresholdScore.accessibility") + @DefaultValue("0.5") + public double lighthouseAssertAccessibility(); + + @Key("neodymium.lighthouse.assert.thresholdScore.bestPractices") + @DefaultValue("0.5") + public double lighthouseAssertBestPractices(); + + @Key("neodymium.lighthouse.assert.thresholdScore.seo") + @DefaultValue("0.5") + public double lighthouseAssertSeo(); + + @Key("neodymium.lighthouse.assert.audits") + public String lighthouseAssertAudits(); + @Key("neodymium.report.showSelenideErrorDetails") @DefaultValue("false") public boolean showSelenideErrorDetails(); diff --git a/src/test/java/com/xceptance/neodymium/util/LighthouseUtilsTest.java b/src/test/java/com/xceptance/neodymium/util/LighthouseUtilsTest.java new file mode 100644 index 00000000..001c0294 --- /dev/null +++ b/src/test/java/com/xceptance/neodymium/util/LighthouseUtilsTest.java @@ -0,0 +1,221 @@ +package com.xceptance.neodymium.util; + +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.lang.reflect.Method; + +import org.junit.Assert; + +import com.codeborne.selenide.Selenide; +import com.xceptance.neodymium.common.browser.Browser; +import com.xceptance.neodymium.junit5.NeodymiumTest; + +@Browser("Chrome_headless") +public class LighthouseUtilsTest +{ + @NeodymiumTest + public void testLighthouseUtilsHappyPath() throws Exception + { + Neodymium.configuration().setProperty("neodymium.lighthouse.assert.thresholdScore.performance", "0.5"); + Neodymium.configuration().setProperty("neodymium.lighthouse.assert.thresholdScore.accessiblity", "0.5"); + Neodymium.configuration().setProperty("neodymium.lighthouse.assert.thresholdScore.bestPractices", "0.5"); + Neodymium.configuration().setProperty("neodymium.lighthouse.assert.thresholdScore.seo", "0.5"); + + Class clazz = LighthouseUtils.class; + Method runProcess = clazz.getDeclaredMethod("runProcess", String[].class); + runProcess.setAccessible(true); + Process p = null; + + if (System.getProperty("os.name").toLowerCase().contains("win")) + { + Neodymium.configuration().setProperty("neodymium.lighthouse.binaryPath", "echo {\"categories\": {\"performance\": {\"score\": 0.5}, \"accessibility\": {\"score\": 0.5}, \"best-practices\": {\"score\": 0.5}, \"seo\": {\"score\": 0.5}}} > target/lighthouseUtilsReport.report.json | echo makeCommentWork #"); + p = (Process) runProcess.invoke(null, new Object[]{new String[]{"cmd.exe", "/c", "echo fabricatedHtml > target/lighthouseUtilsReport.report.html"}}); + } + else if (System.getProperty("os.name").toLowerCase().contains("linux") || System.getProperty("os.name").toLowerCase().contains("mac")) + { + try + { + Neodymium.configuration().setProperty("neodymium.lighthouse.binaryPath", "echo {\"categories\": {\"performance\": {\"score\": 0.5}, \"accessibility\": {\"score\": 0.5}, \"best-practices\": {\"score\": 0.5}, \"seo\": {\"score\": 0.5}}} > target/lighthouseUtilsReport.report.json"); + p = (Process) runProcess.invoke(null, new Object[]{new String[]{"sh", "-c", "echo fabricatedHtml > target/lighthouseUtilsReport.report.html"}}); + } + catch (Exception e) + { + p = (Process) runProcess.invoke(null, new Object[]{new String[]{"echo fabricatedHtml > target/lighthouseUtilsReport.report.html"}}); + } + } + else + { + throw new Exception("your current operation system is not supported, please use Windows, Linux or MacOS"); + } + + BufferedReader r = new BufferedReader(new InputStreamReader(p.getInputStream())); + while (r.readLine() != null) + { + continue; + } + + Selenide.open("https://blog.xceptance.com/"); + + LighthouseUtils.createLightHouseReport("lighthouseUtilsReport"); + } + + @NeodymiumTest + public void testLighthouseUtilsPerformanceException() throws Exception + { + Neodymium.configuration().setProperty("neodymium.lighthouse.assert.thresholdScore.performance", "0.51"); + Neodymium.configuration().setProperty("neodymium.lighthouse.assert.thresholdScore.accessibility", "0.5"); + Neodymium.configuration().setProperty("neodymium.lighthouse.assert.thresholdScore.bestPractices", "0.5"); + Neodymium.configuration().setProperty("neodymium.lighthouse.assert.thresholdScore.seo", "0.5"); + + if (System.getProperty("os.name").toLowerCase().contains("win")) + { + Neodymium.configuration().setProperty("neodymium.lighthouse.binaryPath", "echo {\"categories\": {\"performance\": {\"score\": 0.5}, \"accessibility\": {\"score\": 0.5}, \"best-practices\": {\"score\": 0.5}, \"seo\": {\"score\": 0.5}}} > target/lighthouseUtilsReport.report.json | echo makeCommentWork #"); + } + else if (System.getProperty("os.name").toLowerCase().contains("linux") || System.getProperty("os.name").toLowerCase().contains("mac")) + { + Neodymium.configuration().setProperty("neodymium.lighthouse.binaryPath", "echo {\"categories\": {\"performance\": {\"score\": 0.5}, \"accessibility\": {\"score\": 0.5}, \"best-practices\": {\"score\": 0.5}, \"seo\": {\"score\": 0.5}}} > target/lighthouseUtilsReport.report.json"); + } + else + { + throw new Exception("your current operation system is not supported, please use Windows, Linux or MacOS"); + } + + Selenide.open("https://blog.xceptance.com/"); + + try + { + LighthouseUtils.createLightHouseReport("lighthouseUtilsReport"); + } + catch (AssertionError e) + { + Assert.assertTrue("the compared error messages doesn't match", e.getMessage().contains("The Lighthouse performance score 0.5 doesn't exceed nor match the required threshold of 0.51, please improve the score to match expectations")); + } + } + + @NeodymiumTest + public void testLighthouseUtilsAccessibilityException() throws Exception + { + Neodymium.configuration().setProperty("neodymium.lighthouse.assert.thresholdScore.performance", "0.5"); + Neodymium.configuration().setProperty("neodymium.lighthouse.assert.thresholdScore.accessibility", "0.51"); + Neodymium.configuration().setProperty("neodymium.lighthouse.assert.thresholdScore.bestPractices", "0.5"); + Neodymium.configuration().setProperty("neodymium.lighthouse.assert.thresholdScore.seo", "0.5"); + + if (System.getProperty("os.name").toLowerCase().contains("win")) + { + Neodymium.configuration().setProperty("neodymium.lighthouse.binaryPath", "echo {\"categories\": {\"performance\": {\"score\": 0.5}, \"accessibility\": {\"score\": 0.5}, \"best-practices\": {\"score\": 0.5}, \"seo\": {\"score\": 0.5}}} > target/lighthouseUtilsReport.report.json | echo makeCommentWork #"); + } + else if (System.getProperty("os.name").toLowerCase().contains("linux") || System.getProperty("os.name").toLowerCase().contains("mac")) + { + Neodymium.configuration().setProperty("neodymium.lighthouse.binaryPath", "echo {\"categories\": {\"performance\": {\"score\": 0.5}, \"accessibility\": {\"score\": 0.5}, \"best-practices\": {\"score\": 0.5}, \"seo\": {\"score\": 0.5}}} > target/lighthouseUtilsReport.report.json"); + } + else + { + throw new Exception("your current operation system is not supported, please use Windows, Linux or MacOS"); + } + + Selenide.open("https://blog.xceptance.com/"); + + try + { + LighthouseUtils.createLightHouseReport("lighthouseUtilsReport"); + } + catch (AssertionError e) + { + Assert.assertTrue("the compared error messages doesn't match", e.getMessage().contains("The Lighthouse accessibility score 0.5 doesn't exceed nor match the required threshold of 0.51, please improve the score to match expectations")); + } + } + + @NeodymiumTest + public void testLighthouseUtilsBestPracticesException() throws Exception + { + Neodymium.configuration().setProperty("neodymium.lighthouse.assert.thresholdScore.performance", "0.5"); + Neodymium.configuration().setProperty("neodymium.lighthouse.assert.thresholdScore.accessibility", "0.5"); + Neodymium.configuration().setProperty("neodymium.lighthouse.assert.thresholdScore.bestPractices", "0.51"); + Neodymium.configuration().setProperty("neodymium.lighthouse.assert.thresholdScore.seo", "0.5"); + + if (System.getProperty("os.name").toLowerCase().contains("win")) + { + Neodymium.configuration().setProperty("neodymium.lighthouse.binaryPath", "echo {\"categories\": {\"performance\": {\"score\": 0.5}, \"accessibility\": {\"score\": 0.5}, \"best-practices\": {\"score\": 0.5}, \"seo\": {\"score\": 0.5}}} > target/lighthouseUtilsReport.report.json | echo makeCommentWork #"); + } + else if (System.getProperty("os.name").toLowerCase().contains("linux") || System.getProperty("os.name").toLowerCase().contains("mac")) + { + Neodymium.configuration().setProperty("neodymium.lighthouse.binaryPath", "echo {\"categories\": {\"performance\": {\"score\": 0.5}, \"accessibility\": {\"score\": 0.5}, \"best-practices\": {\"score\": 0.5}, \"seo\": {\"score\": 0.5}}} > target/lighthouseUtilsReport.report.json"); + } + else + { + throw new Exception("your current operation system is not supported, please use Windows, Linux or MacOS"); + } + + Selenide.open("https://blog.xceptance.com/"); + + try + { + LighthouseUtils.createLightHouseReport("lighthouseUtilsReport"); + } + catch (AssertionError e) + { + Assert.assertTrue("the compared error messages doesn't match", e.getMessage().contains("The Lighthouse best practices score 0.5 doesn't exceed nor match the required threshold of 0.51, please improve the score to match expectations")); + } + } + + @NeodymiumTest + public void testLighthouseUtilsSeoException() throws Exception + { + Neodymium.configuration().setProperty("neodymium.lighthouse.assert.thresholdScore.performance", "0.5"); + Neodymium.configuration().setProperty("neodymium.lighthouse.assert.thresholdScore.accessibility", "0.5"); + Neodymium.configuration().setProperty("neodymium.lighthouse.assert.thresholdScore.bestPractices", "0.5"); + Neodymium.configuration().setProperty("neodymium.lighthouse.assert.thresholdScore.seo", "0.51"); + + if (System.getProperty("os.name").toLowerCase().contains("win")) + { + Neodymium.configuration().setProperty("neodymium.lighthouse.binaryPath", "echo {\"categories\": {\"performance\": {\"score\": 0.5}, \"accessibility\": {\"score\": 0.5}, \"best-practices\": {\"score\": 0.5}, \"seo\": {\"score\": 0.5}}} > target/lighthouseUtilsReport.report.json | echo makeCommentWork #"); + } + else if (System.getProperty("os.name").toLowerCase().contains("linux") || System.getProperty("os.name").toLowerCase().contains("mac")) + { + Neodymium.configuration().setProperty("neodymium.lighthouse.binaryPath", "echo {\"categories\": {\"performance\": {\"score\": 0.5}, \"accessibility\": {\"score\": 0.5}, \"best-practices\": {\"score\": 0.5}, \"seo\": {\"score\": 0.5}}} > target/lighthouseUtilsReport.report.json"); + } + else + { + throw new Exception("your current operation system is not supported, please use Windows, Linux or MacOS"); + } + + Selenide.open("https://blog.xceptance.com/"); + + try + { + LighthouseUtils.createLightHouseReport("lighthouseUtilsReport"); + } + catch (AssertionError e) + { + Assert.assertTrue("the compared error messages doesn't match", e.getMessage().contains("The Lighthouse seo score 0.5 doesn't exceed nor match the required threshold of 0.51, please improve the score to match expectations")); + } + } + + @NeodymiumTest + public void testLighthouseUtilsBinNotFound() throws Exception + { + if (System.getProperty("os.name").toLowerCase().contains("win")) + { + Neodymium.configuration().setProperty("neodymium.lighthouse.binaryPath", "programmWhichIsDefinitelyNotInstalled"); + } + else if (System.getProperty("os.name").toLowerCase().contains("linux") || System.getProperty("os.name").toLowerCase().contains("mac")) + { + Neodymium.configuration().setProperty("neodymium.lighthouse.binaryPath", "programmWhichIsDefinitelyNotInstalled"); + } + else + { + throw new Exception("your current operation system is not supported, please use Windows, Linux or MacOS"); + } + + Selenide.open("https://blog.xceptance.com/"); + + try + { + LighthouseUtils.createLightHouseReport("lighthouseUtilsReport"); + } + catch (Exception e) + { + Assert.assertTrue("the compared error messages doesn't match", e.getMessage().contains("lighthouse binary not found at")); + } + } +} \ No newline at end of file