From b9a5cef97ad70c860df1c112ddb05b33e014adb5 Mon Sep 17 00:00:00 2001 From: Anand Bagmar Date: Sat, 8 Jul 2023 10:55:26 +0530 Subject: [PATCH] Download app if URL is provided (#236) * Handling appPath if URL is provided (create repo, download file, install downloaded file) (#226) * Resolved TODO loggingPrefs for firefox. Added setLogLevel, loggingPrefs for createChromeDriver and createFirefoxDriver. * Added 2 methods isURLValid(String) and downloadFile(String, String). Both of these are used in verifyAppExistsAtMentionedPath() where if URL exist we are creating repository, downloading file, then installing the downloaded file on device. * Removed isURLValid(appPath), used isAppPathAUrl(appPath) instead. Added createDirectoryIfNotExist(directoryPath). Rewritten code for simplification * Added Logger to createDirectoryIfNotExist() based on condition. Added Logger, exception throwing in downloadFileIfNotExist(). Create method convertAppPathToFilePathIfNeeded(), and called from verifyAppExistsAtMentionedPath(). Added Logger to isAppPathAUrl() based on condition * made changes according to PR comments * pushing after pulling changes from forked * made convertAppPathToFilePathIfNeeded() public, created unit tests in AppPathTest for convertAppPathToFilePathIfNeeded() * modified method names and code as per comments * changed method naming using given, when, then. Changed to single imports. modified code as per comments * Changed to single imports. Modified code as per comments. Created separate method to open file * made directoryPath as second argument * made changes to directoryPath in variable names, for unit test using temp/unitTests directory. --------- Co-authored-by: Mukund1 Gupta * updated download app functionality * renamed method from convertAppPathToFilePathIfNeeded to downloadAppAndGetFilePath * Removed openFile() method, added and modified Unit Tests (#240) * Resolved TODO loggingPrefs for firefox. Added setLogLevel, loggingPrefs for createChromeDriver and createFirefoxDriver. * Added 2 methods isURLValid(String) and downloadFile(String, String). Both of these are used in verifyAppExistsAtMentionedPath() where if URL exist we are creating repository, downloading file, then installing the downloaded file on device. * Removed isURLValid(appPath), used isAppPathAUrl(appPath) instead. Added createDirectoryIfNotExist(directoryPath). Rewritten code for simplification * Added Logger to createDirectoryIfNotExist() based on condition. Added Logger, exception throwing in downloadFileIfNotExist(). Create method convertAppPathToFilePathIfNeeded(), and called from verifyAppExistsAtMentionedPath(). Added Logger to isAppPathAUrl() based on condition * made changes according to PR comments * pushing after pulling changes from forked * made convertAppPathToFilePathIfNeeded() public, created unit tests in AppPathTest for convertAppPathToFilePathIfNeeded() * modified method names and code as per comments * changed method naming using given, when, then. Changed to single imports. modified code as per comments * Changed to single imports. Modified code as per comments. Created separate method to open file * made directoryPath as second argument * made changes to directoryPath in variable names, for unit test using temp/unitTests directory. * removed openFile() method and its calling from convertAppPathToFilePathIfNeeded() method * modified code, created all 12 possible unit tests * changed unit test method name * modified code as per downloadApp branch and called createDirectory() inside downloadFile() * modified method names for unit tests and method called for downloading file. * add isAppPathAUrl() method to confirm url is valid or invalid after confirming it is an url * change assertions to assertThrows and replace Exception * add conditional code for handling file does not exist or incorrect file path by throwing exception * made changes to unit test assertions, replaced with assertThrows to catch exceptions * add methods checkEitherFilePathIsIncorrectOrFileIsMissing(), downloadFileIfDoesNotExist() --------- Co-authored-by: Mukund1 Gupta * fixed and optimised downloadApp if URL is given functionality. Updated tests. --------- Co-authored-by: Mukund Gupta Co-authored-by: Mukund1 Gupta --- .../com/znsio/teswiz/runner/DeviceSetup.java | 192 +++++++++++++++--- .../com/znsio/teswiz/runner/AppPathTest.java | 149 ++++++++++++++ 2 files changed, 312 insertions(+), 29 deletions(-) create mode 100644 src/test/java/com/znsio/teswiz/runner/AppPathTest.java diff --git a/src/main/java/com/znsio/teswiz/runner/DeviceSetup.java b/src/main/java/com/znsio/teswiz/runner/DeviceSetup.java index c095de830..39f44922f 100644 --- a/src/main/java/com/znsio/teswiz/runner/DeviceSetup.java +++ b/src/main/java/com/znsio/teswiz/runner/DeviceSetup.java @@ -7,12 +7,19 @@ import com.znsio.teswiz.tools.cmd.CommandLineExecutor; import com.znsio.teswiz.tools.cmd.CommandLineResponse; import org.apache.log4j.Logger; +import org.jetbrains.annotations.NotNull; import java.io.File; import java.io.IOException; +import java.io.InputStream; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URL; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.nio.file.StandardCopyOption; +import java.text.DecimalFormat; import java.util.ArrayList; import java.util.Map; import java.util.Objects; @@ -31,6 +38,9 @@ class DeviceSetup { private static final Logger LOGGER = Logger.getLogger(DeviceSetup.class.getName()); + private static final String DEFAULT_TEMP_SAMPLE_APP_DIRECTORY = + System.getProperty("user.dir") + File.separator + + "temp" + File.separator + "sampleApps"; private DeviceSetup() { LOGGER.debug("DeviceSetup - private constructor"); @@ -65,10 +75,10 @@ static String getPathForFileInLogDir(String fullFilePath) { static ArrayList setupAndroidExecution() { ArrayList androidCukeArgs = new ArrayList<>(); - if(Setup.getPlatform().equals(Platform.android)) { + if (Setup.getPlatform().equals(Platform.android)) { verifyAppExistsAtMentionedPath(); fetchAndroidAppVersion(); - if(Setup.getBooleanValueFromConfigs(RUN_IN_CI)) { + if (Setup.getBooleanValueFromConfigs(RUN_IN_CI)) { setupCloudExecution(); } else { LocalDevicesSetup.setupLocalExecution(); @@ -86,22 +96,121 @@ static ArrayList setupAndroidExecution() { static void verifyAppExistsAtMentionedPath() { String appPath = Setup.getFromConfigs(APP_PATH); LOGGER.info(String.format("Update path to Apk: %s", appPath)); - if(appPath.equals(NOT_SET)) { + if (appPath.equals(NOT_SET)) { appPath = getAppPathFromCapabilities(); + appPath = downloadAppToDirectoryIfNeeded(appPath, DEFAULT_TEMP_SAMPLE_APP_DIRECTORY); Setup.addToConfigs(APP_PATH, appPath); - String capabilitiesFileName = Setup.getFromConfigs(CAPS); - checkIfAppExistsAtTheMentionedPath(appPath, capabilitiesFileName); } else { + appPath = downloadAppToDirectoryIfNeeded(appPath, DEFAULT_TEMP_SAMPLE_APP_DIRECTORY); LOGGER.info(String.format("\tUsing AppPath provided as environment variable - %s", - appPath)); + appPath)); + } + } + + public static String downloadAppToDirectoryIfNeeded(String appPath, String saveToLocalDirectory) { + String fileName = appPath.split(File.separator)[appPath.split(File.separator).length - 1]; + String localFilePath = saveToLocalDirectory + File.separator + fileName; + if (isAppPathAUrl(appPath)) { + LOGGER.info(String.format("App url '%s' is provided in capabilities. Download it, if " + + "not already available at '%s'", appPath, localFilePath)); + downloadFileIfDoesNotExist(appPath, localFilePath, saveToLocalDirectory); + LOGGER.info("Changing value of appPath from URL to file path"); + LOGGER.info(String.format("Before change, appPath value: %s", appPath)); + appPath = localFilePath; + LOGGER.info(String.format("After change, appPath value: %s", localFilePath)); + } else { + LOGGER.info(String.format("App file path '%s' is provided in capabilities.", appPath)); + if (!(new File(appPath).exists())) { + throw new InvalidTestDataException(String.format("App file path '%s' provided in capabilities is incorrect", appPath)); +// checkEitherFilePathIsIncorrectOrFileIsMissing(appPath, localFilePath); + } + } + LOGGER.info(String.format("App file path '%s' is provided in capabilities.", appPath)); + LOGGER.info(String.format("File available at App file path '%s'", appPath)); + return appPath; + } + + private static void createDirectory(String directoryPath) { + try { + LOGGER.info("Directory doesn't exist, Creating directory"); + Files.createDirectories(Path.of(directoryPath)); + } catch (IOException e) { + throw new RuntimeException(String.format("Failed to create directory: %s, error occurred%s", directoryPath, e)); + } + } + + private static void downloadFile(String url, String filePath, String saveToDirectory) { + LOGGER.info(String.format("Downloading App from url: '%s'", url)); + try { + URL fileUrl = new URL(url); + HttpURLConnection connection = getHttpURLConnection(fileUrl); + downloadFileFromHttpURL(filePath, saveToDirectory, connection); + String formattedSize = getDownloadedAppSize(Path.of(filePath)); + LOGGER.info(String.format("App downloaded at path: '%s', having size: '%s MB'", filePath, formattedSize)); + } catch (IOException e) { + throw new InvalidTestDataException("An error occurred while opening the URL/downloading file: " + e.getMessage()); + } + } + + private static String getDownloadedAppSize(Path filePath) { + long fileSizeBytes = 0; + try { + fileSizeBytes = Files.size(filePath); + } catch (IOException e) { + throw new InvalidTestDataException("Unable to get downloaded app file size. Download " + + "may be corrupt. Check and fix before " + + "rerunning the test.", e); + } + double fileSizeMB = (double) fileSizeBytes / (1024 * 1024); + return new DecimalFormat("#.##").format(fileSizeMB); + } + + private static void downloadFileFromHttpURL(String filePath, String saveToDirectory, HttpURLConnection connection) { + try (InputStream inputStream = connection.getInputStream()) { + createDirectoryIfNotExists(saveToDirectory); + Files.copy(inputStream, Path.of(filePath), StandardCopyOption.REPLACE_EXISTING); + } catch (IOException e) { + throw new InvalidTestDataException(String.format("Unable to download file '%s'", connection.getURL().toString()), e); + } + } + + @NotNull + private static HttpURLConnection getHttpURLConnection(URL fileUrl) { + try { + HttpURLConnection connection = (HttpURLConnection) fileUrl.openConnection(); + connection.setRequestMethod("GET"); + + int responseCode = connection.getResponseCode(); + if (responseCode != HttpURLConnection.HTTP_OK) { + throw new InvalidTestDataException(String.format("Unable to connect to url: '%s'. Got connection error '%d'", fileUrl, responseCode)); + } + return connection; + } catch (IOException e) { + throw new InvalidTestDataException(String.format("Unable to connect to url: '%s'.", fileUrl)); + } + } + + private static void createDirectoryIfNotExists(String directory) throws IOException { + Path directoryPath = Path.of(directory); + if (!Files.exists(directoryPath)) { + Files.createDirectories(directoryPath); + } + } + + private static void downloadFileIfDoesNotExist(String appPath, String filePath, String saveToDirectory){ + if (!(new File(filePath).exists())) { + LOGGER.info(String.format("App is not available at path: '%s'. Download it.", appPath)); + downloadFile(appPath, filePath, saveToDirectory); + } else { + LOGGER.info(String.format("App is already available at path: '%s'. No need to download it.", appPath)); } } private static void fetchAndroidAppVersion() { Pattern versionNamePattern = Pattern.compile("versionName='(\\d+(\\.\\d+)+)'", - Pattern.MULTILINE); + Pattern.MULTILINE); String searchPattern = "grep"; - if(Runner.IS_WINDOWS) { + if (Runner.IS_WINDOWS) { searchPattern = "findstr"; } @@ -115,11 +224,11 @@ private static void fetchAndroidAppVersion() { File aaptExecutable = new File(buildVersionFolder, "aapt").getAbsoluteFile(); String[] commandToGetAppVersion = new String[]{aaptExecutable.toString(), "dump", - "badging", appFilePath, "|", - searchPattern, "versionName"}; + "badging", appFilePath, "|", + searchPattern, "versionName"}; fetchAppVersion(commandToGetAppVersion, versionNamePattern); } - } catch(Exception e) { + } catch (Exception e) { LOGGER.info( String.format("fetchAndroidAppVersion: Exception: %s", e.getLocalizedMessage())); } @@ -128,7 +237,7 @@ private static void fetchAndroidAppVersion() { static void setupCloudExecution() { String cloudName = getCloudNameFromCapabilities(); String deviceLabURL = NOT_SET; - switch(cloudName.toLowerCase()) { + switch (cloudName.toLowerCase()) { case "headspin": deviceLabURL = getCloudUrlFromCapabilities(); HeadSpinSetup.updateHeadspinCapabilities(deviceLabURL); @@ -152,16 +261,15 @@ static void setupCloudExecution() { private static String getAppPathFromCapabilities() { String capabilityFile = Setup.getFromConfigs(CAPS); - return JsonFile.getNodeValueAsStringFromJsonFile(capabilityFile, - new String[]{Setup.getPlatform().name(), "app"}); + return JsonFile.getNodeValueAsStringFromJsonFile(capabilityFile, new String[]{Setup.getPlatform().name(), "app"}); } private static void checkIfAppExistsAtTheMentionedPath(String appPath, String capabilitiesFileName) { - if(!isAppPathAUrl(appPath)) { - if(Files.exists(Paths.get(appPath))) { + if (!isAppPathAUrl(appPath)) { + if (Files.exists(Paths.get(appPath))) { LOGGER.info(String.format("\tUsing AppPath: %s in file: %s:: %s", appPath, - capabilitiesFileName, Setup.getPlatform())); + capabilitiesFileName, Setup.getPlatform())); } else { LOGGER.info(String.format("\tAppPath: %s not found!", appPath)); throw new InvalidTestDataException( @@ -170,19 +278,45 @@ private static void checkIfAppExistsAtTheMentionedPath(String appPath, } } - private static boolean isAppPathAUrl(String appPath) { - boolean isUrl = appPath.toLowerCase().startsWith("http"); - LOGGER.info(String.format("\tAppPath refers to a url: %s", appPath)); - return isUrl; + private static boolean isAppPathAUrl(String appPathUrl) { + URL url; + try { + url = new URL(appPathUrl); + LOGGER.info(String.format("'%s' is a URL.", appPathUrl)); + isAppUrlValid(appPathUrl); + return true; + } catch (MalformedURLException e) { + LOGGER.info(String.format("'%s' is not a URL.", appPathUrl)); + return false; + } + } + + private static void isAppUrlValid(String appPathUrl) { + int responseCode; + HttpURLConnection connection; + try { + connection = (HttpURLConnection) new URL(appPathUrl).openConnection(); + connection.setRequestMethod("HEAD"); + responseCode = connection.getResponseCode(); + connection.disconnect(); + } catch (IOException e) { + throw new InvalidTestDataException(String.format("Failed to make a connection using url: '%s'", appPathUrl) + e); + } + + if (responseCode != HttpURLConnection.HTTP_OK) { + LOGGER.info(String.format("'%s' is an invalid URL.", appPathUrl)); + throw new InvalidTestDataException("URL is not accessible: " + appPathUrl); + } + LOGGER.info(String.format("'%s' is a valid URL.", appPathUrl)); } private static void fetchAppVersion(String[] commandToGetAppVersion, Pattern pattern) { CommandLineResponse commandResponse = CommandLineExecutor.execCommand( commandToGetAppVersion); String commandOutput = commandResponse.getStdOut(); - if(!(null == commandOutput || commandOutput.isEmpty())) { + if (!(null == commandOutput || commandOutput.isEmpty())) { Matcher matcher = pattern.matcher(commandOutput); - if(matcher.find()) { + if (matcher.find()) { Setup.addToConfigs(APP_VERSION, matcher.group(1)); LOGGER.info(String.format("APP_VERSION: %s", matcher.group(1))); } @@ -214,7 +348,7 @@ private static String getCloudApiUrlFromCapabilities() { static ArrayList setupWindowsExecution() { ArrayList windowsCukeArgs = new ArrayList<>(); - if(Setup.getPlatform().equals(Platform.windows)) { + if (Setup.getPlatform().equals(Platform.windows)) { verifyAppExistsAtMentionedPath(); fetchWindowsAppVersion(); windowsCukeArgs.add(PLUGIN); @@ -231,12 +365,12 @@ private static void fetchWindowsAppVersion() { try { File appFile = new File(Setup.getFromConfigs(APP_PATH)); String nameVariable = "name=\"" + appFile.getCanonicalPath() - .replace("\\", "\\\\") + "\""; + .replace("\\", "\\\\") + "\""; String[] commandToGetAppVersion = new String[]{"wmic", "datafile", "where", - nameVariable, "get", "Version", - "/value"}; + nameVariable, "get", "Version", + "/value"}; fetchAppVersion(commandToGetAppVersion, versionNamePattern); - } catch(IOException e) { + } catch (IOException e) { LOGGER.info( String.format("fetchWindowsAppVersion: Exception: %s", e.getLocalizedMessage())); } @@ -244,7 +378,7 @@ private static void fetchWindowsAppVersion() { static void cleanupCloudExecution() { String cloudName = getCloudNameFromCapabilities(); - switch(cloudName.toLowerCase()) { + switch (cloudName.toLowerCase()) { case "browserstack": BrowserStackSetup.cleanUp(); break; diff --git a/src/test/java/com/znsio/teswiz/runner/AppPathTest.java b/src/test/java/com/znsio/teswiz/runner/AppPathTest.java new file mode 100644 index 000000000..84738896a --- /dev/null +++ b/src/test/java/com/znsio/teswiz/runner/AppPathTest.java @@ -0,0 +1,149 @@ +package com.znsio.teswiz.runner; + +import com.znsio.teswiz.exceptions.InvalidTestDataException; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; + +import static org.junit.jupiter.api.Assertions.*; + +public class AppPathTest { + private static final String LOG_DIR = "./target/testLogs"; + private static final String directoryPath = System.getProperty("user.dir") + File.separator + "temp" + File.separator + "unitTests" + File.separator + "sampleApps"; + private static final String fileName = "VodQA.apk"; + private static final String expectedAppPath = directoryPath + File.separator + fileName; + private static final String appPathAsCorrectUrl = "https://github.com/anandbagmar/sampleAppsForNativeMobileAutomation/raw/main/VodQA.apk"; + private static final String appPathAsIncorrectUrl = "https://github.com/anandbagmar/sampleAppsForNativeMobileAutomation/ra/main/VodQA.apk"; + private static final String appPathAsCorrectFilePath = expectedAppPath; + private static final String appPathAsIncorrectFilePath = System.getProperty("user.dir") + File.separator + "temp" + File.separator + "unitTests" + File.separator + "smleApps" + File.separator + fileName; + + @BeforeAll + public static void setupBefore() { + System.setProperty("LOG_DIR", LOG_DIR); + new File(LOG_DIR).mkdirs(); + } + + @Test + void givenIncorrectUrl_WhenDirectoryAndFileDoNotExist_ThenIOExceptionOccurWhileTryingToDownloadFile() { + deleteDirectoryUsedForUnitTests(); + assertThrows(InvalidTestDataException.class, () -> DeviceSetup.downloadAppToDirectoryIfNeeded(appPathAsIncorrectUrl, directoryPath)); + } + + @Test + void givenIncorrectUrl_WhenDirectoryExistAndFileDoNotExist_ThenIOExceptionOccurWhileTryingToDownloadFile() { + createDirectoryUsedForUnitTests(); + deleteFile(appPathAsCorrectFilePath); + assertThrows(InvalidTestDataException.class, () -> DeviceSetup.downloadAppToDirectoryIfNeeded(appPathAsIncorrectUrl, directoryPath)); + } + + @Test + void givenIncorrectUrl_WhenDirectoryAndFileBothExist_ThenFileIsReadable() { + createDirectoryUsedForUnitTests(); + DeviceSetup.downloadAppToDirectoryIfNeeded(appPathAsCorrectUrl, directoryPath); + assertThrows(InvalidTestDataException.class, () -> DeviceSetup.downloadAppToDirectoryIfNeeded(appPathAsIncorrectUrl, directoryPath)); + } + + @Test + void givenCorrectUrl_WhenDirectoryAndFileDoNotExist_ThenCreateDirectoryAndDownloadFile() { + deleteDirectoryUsedForUnitTests(); + String actualAppPath = DeviceSetup.downloadAppToDirectoryIfNeeded(appPathAsCorrectUrl, directoryPath); + assertEquals(expectedAppPath, actualAppPath); + assertTrue(new File(actualAppPath).canRead()); + } + + @Test + void givenCorrectUrl_WhenDirectoryExistButFileDoNotExist_ThenDownloadFile() { + createDirectoryUsedForUnitTests(); + deleteFile(appPathAsCorrectFilePath); + String actualAppPath = DeviceSetup.downloadAppToDirectoryIfNeeded(appPathAsCorrectUrl, directoryPath); + assertEquals(expectedAppPath, actualAppPath); + assertTrue(new File(actualAppPath).canRead()); + } + + @Test + void givenCorrectUrl_WhenDirectoryAndFileAlreadyExist_ThenDoNotDownloadFile() { + createDirectoryUsedForUnitTests(); + DeviceSetup.downloadAppToDirectoryIfNeeded(appPathAsCorrectUrl, directoryPath); + assertTrue(new File(expectedAppPath).canRead()); + String actualAppPath = DeviceSetup.downloadAppToDirectoryIfNeeded(appPathAsCorrectUrl, directoryPath); + assertTrue(new File(actualAppPath).canRead()); + assertEquals(expectedAppPath, actualAppPath); + } + + @Test + void givenIncorrectFilePath_WhenDirectoryAndFileDoNotExist_ThenFileIsNotReadable() { + deleteDirectoryUsedForUnitTests(); + assertThrows(InvalidTestDataException.class, () -> DeviceSetup.downloadAppToDirectoryIfNeeded(appPathAsIncorrectFilePath, directoryPath)); + } + + @Test + void givenIncorrectFilePath_WhenDirectoryExistButFileDoNotExist_ThenFileIsNotReadable() { + createDirectoryUsedForUnitTests(); + deleteFile(appPathAsCorrectFilePath); + assertThrows(InvalidTestDataException.class, () -> DeviceSetup.downloadAppToDirectoryIfNeeded(appPathAsIncorrectFilePath, directoryPath)); + } + + @Test + void givenIncorrectFilePath_WhenDirectoryAndFileExist_ThenFileIsNotReadable() { + createDirectoryUsedForUnitTests(); + assertThrows(InvalidTestDataException.class, () -> DeviceSetup.downloadAppToDirectoryIfNeeded(appPathAsIncorrectFilePath, directoryPath)); + } + + @Test + void givenCorrectFilePath_WhenDirectoryAndFileDoNotExist_ThenFileIsNotReadable() { + deleteDirectoryUsedForUnitTests(); + assertThrows(RuntimeException.class, () -> DeviceSetup.downloadAppToDirectoryIfNeeded(appPathAsCorrectFilePath, directoryPath)); + } + + @Test + void givenCorrectFilePath_WhenDirectoryExistButFileDoNotExist_ThenFileIsNotReadable() { + createDirectoryUsedForUnitTests(); + deleteFile(appPathAsCorrectFilePath); + assertThrows(RuntimeException.class, () -> DeviceSetup.downloadAppToDirectoryIfNeeded(appPathAsCorrectFilePath, directoryPath)); + } + + @Test + void givenCorrectFilePath_WhenDirectoryAndFileAlreadyExist_ThenFileIsReadable() { + createDirectoryUsedForUnitTests(); + DeviceSetup.downloadAppToDirectoryIfNeeded(appPathAsCorrectUrl, directoryPath); + String actualAppPath = DeviceSetup.downloadAppToDirectoryIfNeeded(appPathAsCorrectFilePath, directoryPath); + assertTrue(new File(actualAppPath).canRead()); + assertEquals(expectedAppPath, actualAppPath); + } + + private void deleteFile(String filePath) { + try { + Files.deleteIfExists(Path.of(filePath)); + } catch (IOException e) { + throw new RuntimeException("Failed to delete file for unit test: " + e.getMessage()); + } + } + + private void deleteDirectoryUsedForUnitTests() { + if (Files.exists(Paths.get(AppPathTest.directoryPath))) { + try { + Files.walk(Paths.get(AppPathTest.directoryPath)) + .sorted(java.util.Comparator.reverseOrder()) + .map(Path::toFile) + .forEach(java.io.File::delete); + } catch (IOException e) { + System.err.println("Failed to delete folder for unit test: " + e.getMessage()); + } + } + } + + private void createDirectoryUsedForUnitTests() { + if (!Files.exists(Paths.get(AppPathTest.directoryPath))) { + try { + Files.createDirectories(Paths.get(AppPathTest.directoryPath)); + } catch (IOException e) { + System.err.println("Failed to create directory: " + AppPathTest.directoryPath + " for unit test, error occurred" + e); + } + } + } +}