diff --git a/bellatrix.core/src/main/java/solutions/bellatrix/core/plugins/junit/BaseTest.java b/bellatrix.core/src/main/java/solutions/bellatrix/core/plugins/junit/BaseTest.java index a4526c6c..7f313285 100644 --- a/bellatrix.core/src/main/java/solutions/bellatrix/core/plugins/junit/BaseTest.java +++ b/bellatrix.core/src/main/java/solutions/bellatrix/core/plugins/junit/BaseTest.java @@ -31,23 +31,10 @@ public class BaseTest extends UsesPlugins { static final ThreadLocal CURRENT_TEST_RESULT = new ThreadLocal<>(); static final ThreadLocal CURRENT_TEST_TIME_RECORD = ThreadLocal.withInitial(TimeRecord::new); - private static final ThreadLocal CONFIGURATION_EXECUTED = new ThreadLocal<>(); + private static final ThreadLocal CONFIGURATION_EXECUTED = ThreadLocal.withInitial(() -> false); private static final List ALREADY_EXECUTED_BEFORE_CLASSES = Collections.synchronizedList(new ArrayList<>()); private TestInfo testInfo; - public BaseTest() { -// try { -// Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe"); -// theUnsafe.setAccessible(true); -// Unsafe u = (Unsafe)theUnsafe.get(null); -// -// Class cls = Class.forName("jdk.internal.module.IllegalAccessLogger"); -// Field logger = cls.getDeclaredField("logger"); -// u.putObjectVolatile(cls, u.staticFieldOffset(logger), null); -// } catch (Exception ignored) {} - CONFIGURATION_EXECUTED.set(false); - } - @BeforeEach public void beforeMethodCore(TestInfo testInfo) throws Exception { try { diff --git a/bellatrix.core/src/main/java/solutions/bellatrix/core/utilities/ShutdownManager.java b/bellatrix.core/src/main/java/solutions/bellatrix/core/utilities/ShutdownManager.java new file mode 100644 index 00000000..24d159ba --- /dev/null +++ b/bellatrix.core/src/main/java/solutions/bellatrix/core/utilities/ShutdownManager.java @@ -0,0 +1,75 @@ +/* + * Copyright 2024 Automate The Planet Ltd. + * Author: Miriam Kyoseva + * Licensed under the Apache License, Version 2.0 (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package solutions.bellatrix.core.utilities; + +import lombok.experimental.UtilityClass; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; + +@UtilityClass +public class ShutdownManager { + private static final List instructions = new CopyOnWriteArrayList<>(); + private static final ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()); + + static { + Runtime.getRuntime().addShutdownHook(new Thread(ShutdownManager::runAllInstructions)); + } + + public static void register(Runnable runnable) { + instructions.add(runnable); + } + + private static void runAllInstructions() { + if (instructions.isEmpty()) return; + + try { + // Submit all instructions for parallel execution + for (var instruction : instructions) { + executor.submit(() -> { + try { + instruction.run(); + } catch (Exception ex) { + DebugInformation.debugInfo(ex.getMessage()); + } + }); + } + } finally { + shutdownAndAwaitTermination(executor); + } + } + + private static void shutdownAndAwaitTermination(ExecutorService executor) { + executor.shutdown(); // Disable new tasks from being submitted + try { + // Wait a while for existing tasks to terminate + if (!executor.awaitTermination(60, TimeUnit.SECONDS)) { + executor.shutdownNow(); // Cancel currently executing tasks + // Wait a while for tasks to respond to being cancelled + if (!executor.awaitTermination(60, TimeUnit.SECONDS)) { + System.err.println("Executor did not terminate."); + } + } + } catch (InterruptedException ie) { + // (Re-)Cancel if current thread also interrupted + executor.shutdownNow(); + // Preserve interrupt status + Thread.currentThread().interrupt(); + } + } +} \ No newline at end of file diff --git a/bellatrix.core/src/main/java/solutions/bellatrix/core/utilities/SingletonFactory.java b/bellatrix.core/src/main/java/solutions/bellatrix/core/utilities/SingletonFactory.java index b942c054..8b44851f 100644 --- a/bellatrix.core/src/main/java/solutions/bellatrix/core/utilities/SingletonFactory.java +++ b/bellatrix.core/src/main/java/solutions/bellatrix/core/utilities/SingletonFactory.java @@ -55,6 +55,14 @@ public static void register(Class classKey, T instance) { mapHolder.get().put(classKey, instance); } + public static boolean containsKey(Class classOf) { + return mapHolder.get().containsKey(classOf); + } + + public static boolean containsValue(Object object) { + return mapHolder.get().containsValue(object); + } + public static void clear() { mapHolder.get().clear(); } diff --git a/bellatrix.playwright/src/main/java/solutions/bellatrix/playwright/components/shadowdom/ShadowDomService.java b/bellatrix.playwright/src/main/java/solutions/bellatrix/playwright/components/shadowdom/ShadowDomService.java index dbfea39d..f5177574 100644 --- a/bellatrix.playwright/src/main/java/solutions/bellatrix/playwright/components/shadowdom/ShadowDomService.java +++ b/bellatrix.playwright/src/main/java/solutions/bellatrix/playwright/components/shadowdom/ShadowDomService.java @@ -106,25 +106,8 @@ private static String[] getAbsoluteCss(ShadowRoot shadowRoot, String locator) { .evaluate(String.format("(el, [locator]) => (%s)(el, locator)", javaScript), new Object[] { locator })) .toArray(String[]::new); }; - if (Wait.retry(() -> { - String[] foundElements; - try { - foundElements = js.call(); - } catch (Exception e) { - throw new RuntimeException(e); - } - if (foundElements == null || foundElements.length == 0) { - throw new IllegalArgumentException(); - } - }, Duration.ofSeconds(ConfigurationService.get(WebSettings.class).getTimeoutSettings().getElementWaitTimeout()), Duration.ofSeconds(1), false)) { - try { - return js.call(); - } catch (Exception e) { - throw new RuntimeException(e); - } - } else { - throw new IllegalArgumentException("No elements inside the shadow DOM were found with the locator: " + locator); - } + + return getCss(js, locator); } private static String[] getRelativeCss(ShadowRoot shadowRoot, String locator, String parentLocator) { @@ -134,10 +117,14 @@ private static String[] getRelativeCss(ShadowRoot shadowRoot, String locator, St .toArray(String[]::new); }; + return getCss(js, locator); + } + + private static String[] getCss(Callable callable, String locator) { if(Wait.retry(() -> { String[] foundElements; try { - foundElements = js.call(); + foundElements = callable.call(); } catch (Exception e) { throw new RuntimeException(e); } @@ -146,7 +133,7 @@ private static String[] getRelativeCss(ShadowRoot shadowRoot, String locator, St } }, Duration.ofSeconds(ConfigurationService.get(WebSettings.class).getTimeoutSettings().getElementWaitTimeout()), Duration.ofSeconds(1), false)) { try { - return js.call(); + return callable.call(); } catch (Exception e) { throw new RuntimeException(e); } @@ -154,7 +141,6 @@ private static String[] getRelativeCss(ShadowRoot shadowRoot, String locator, St throw new IllegalArgumentException("No elements inside the shadow DOM were found with the locator: " + locator); } } - private static TComponent buildMissingShadowRootsAndCreate(Class clazz, ShadowRoot parentComponent, Ref fullCss) { var component = InstanceFactory.create(clazz); diff --git a/bellatrix.playwright/src/main/java/solutions/bellatrix/playwright/infrastructure/PlaywrightService.java b/bellatrix.playwright/src/main/java/solutions/bellatrix/playwright/infrastructure/PlaywrightService.java index 1da0af99..a712d009 100644 --- a/bellatrix.playwright/src/main/java/solutions/bellatrix/playwright/infrastructure/PlaywrightService.java +++ b/bellatrix.playwright/src/main/java/solutions/bellatrix/playwright/infrastructure/PlaywrightService.java @@ -20,10 +20,12 @@ import com.microsoft.playwright.Playwright; import io.restassured.RestAssured; import io.restassured.http.ContentType; -import lombok.experimental.UtilityClass; +import lombok.Getter; import org.apache.commons.lang3.NotImplementedException; import solutions.bellatrix.core.configuration.ConfigurationService; import solutions.bellatrix.core.utilities.DebugInformation; +import solutions.bellatrix.core.utilities.ShutdownManager; +import solutions.bellatrix.core.utilities.SingletonFactory; import solutions.bellatrix.core.utilities.TimestampBuilder; import solutions.bellatrix.playwright.configuration.GridSettings; import solutions.bellatrix.playwright.configuration.WebSettings; @@ -42,204 +44,206 @@ import java.util.Properties; @SuppressWarnings("ALL") -@UtilityClass public class PlaywrightService { - private static final ThreadLocal DISPOSED; - private static final ThreadLocal BROWSER_CONFIGURATION_THREAD_LOCAL; - private static final ThreadLocal PLAYWRIGHT_THREAD_LOCAL; - private static final ThreadLocal BROWSER_WRAPPER_THREAD_LOCAL; - private static boolean isBuildNameSet = false; - private static String buildName; + private static ThreadLocal PLAYWRIGHT_MANAGER = new ThreadLocal<>(); static { - DISPOSED = ThreadLocal.withInitial(() -> true); - BROWSER_CONFIGURATION_THREAD_LOCAL = new ThreadLocal<>(); - PLAYWRIGHT_THREAD_LOCAL = new ThreadLocal<>(); - BROWSER_WRAPPER_THREAD_LOCAL = new ThreadLocal<>(); + var driverManager = new PlaywrightManager(); + SingletonFactory.register(driverManager); + ShutdownManager.register(driverManager::close); + PLAYWRIGHT_MANAGER.set(driverManager); } public static WrappedBrowser start(BrowserConfiguration configuration) { - if (DISPOSED.get()) { - browserConfiguration(configuration); - playwright(Playwright.create()); - DISPOSED.set(false); - var executionType = Settings.web().getExecutionType(); - - if (executionType.equals("regular")) { - return initializeBrowserWrapperRegularMode(); - } else { - var gridSettings = ConfigurationService.get(WebSettings.class).getGridSettings().stream().filter(g -> g.getProviderName().equals(executionType.toLowerCase())).findFirst().orElse(null); - assert gridSettings != null : String.format("The specified execution type '%s' is not declared in the configuration", executionType); - - return initializeBrowserWrapperGridMode(gridSettings); - } - } - else return wrappedBrowser(); + return PLAYWRIGHT_MANAGER.get().start(configuration); + } + + public static void restartBrowserContext() { + PLAYWRIGHT_MANAGER.get().restartBrowserContext(); } public static void close() { - if (DISPOSED.get()) { - return; - } - - if (playwright() != null) { - DebugInformation.debugInfo("SHUTTING DOWN PLAYWRIGHT"); - - if (wrappedBrowser() != null) { - wrappedBrowser().close(); - } - - PLAYWRIGHT_THREAD_LOCAL.remove(); - - if (wrappedBrowser().getGridSessionId() != null) { - RestAssured.baseURI = ConfigurationService.get(WebSettings.class).getGridSettings().stream().filter(g -> g.getProviderName().equals(Settings.web().getExecutionType().toLowerCase())).findFirst().orElse(null).getUrl(); - - var response = RestAssured.given() - .delete(String.format("/session/%s", wrappedBrowser().getGridSessionId())); - } - } - - DISPOSED.set(true); + PLAYWRIGHT_MANAGER.get().close(); } - public static void restartBrowserContext() { - DebugInformation.debugInfo("RESTARTING CONTEXT"); - wrappedBrowser().changeContext(intializeBrowserContext()); + public static WrappedBrowser wrappedBrowser() { + return PLAYWRIGHT_MANAGER.get().wrappedBrowser; } - private static WrappedBrowser initializeBrowserWrapperRegularMode() { - wrappedBrowser(new WrappedBrowser(playwright())); - - wrappedBrowser().setBrowser(initializeBrowserRegularMode()); - wrappedBrowser().setCurrentContext(intializeBrowserContext()); - wrappedBrowser().setCurrentPage(wrappedBrowser().getCurrentContext().newPage()); - - return wrappedBrowser(); + public static void wrappedBrowser(WrappedBrowser driver) { + PLAYWRIGHT_MANAGER.get().wrappedBrowser = driver; } - private static WrappedBrowser initializeBrowserWrapperGridMode(GridSettings gridSettings) { - wrappedBrowser(new WrappedBrowser(playwright())); - - wrappedBrowser().setBrowser(initializeBrowserGridMode(gridSettings)); - wrappedBrowser().setCurrentContext(intializeBrowserContext()); - wrappedBrowser().setCurrentPage(wrappedBrowser().getCurrentContext().newPage()); - - return wrappedBrowser(); + public static BrowserConfiguration browserConfiguration() { + return PLAYWRIGHT_MANAGER.get().browserConfiguration; } - private static Browser initializeBrowserRegularMode() { - BrowserTypes browserTypes = browserConfiguration().getBrowserTypes(); - - switch (browserTypes) { - case CHROMIUM -> { - var browserType = playwright().chromium(); - BrowserType.LaunchOptions launchOptions = new BrowserType.LaunchOptions(); - launchOptions.setHeadless(false); - launchOptions.setArgs(List.of("--log-level=3", "--remote-allow-origins=*")); - launchOptions.setTimeout(Settings.web().getArtificialDelayBeforeAction()); - // System.setProperty("webdriver.chrome.silentOutput", "true"); ? - - return browser(browserType.launch(launchOptions)); - } - case CHROMIUM_HEADLESS -> { - var browserType = playwright().chromium(); - BrowserType.LaunchOptions launchOptions = new BrowserType.LaunchOptions(); - launchOptions.setHeadless(true); - launchOptions.setArgs(List.of("--log-level=3")); - // System.setProperty("webdriver.chrome.silentOutput", "true"); ? - - return browser(browserType.launch(launchOptions)); - } - case CHROME -> { - var browserType = playwright().chromium(); - BrowserType.LaunchOptions launchOptions = new BrowserType.LaunchOptions(); - launchOptions.setChannel("chrome"); - launchOptions.setHeadless(false); - launchOptions.setArgs(List.of("--log-level=3", "--remote-allow-origins=*", "--disable-search-engine-choice-screen")); - launchOptions.setTimeout(Settings.web().getArtificialDelayBeforeAction()); - // System.setProperty("webdriver.chrome.silentOutput", "true"); ? - - return browser(browserType.launch(launchOptions)); - } - case CHROME_HEADLESS -> { - var browserType = playwright().chromium(); - BrowserType.LaunchOptions launchOptions = new BrowserType.LaunchOptions(); - launchOptions.setChannel("chrome"); - launchOptions.setHeadless(true); - launchOptions.setArgs(List.of("--log-level=3", "--disable-search-engine-choice-screen")); - // System.setProperty("webdriver.chrome.silentOutput", "true"); ? - - return browser(browserType.launch(launchOptions)); + private static class PlaywrightManager { + private PlaywrightManager() { + } + private boolean disposed = true; + @Getter private BrowserConfiguration browserConfiguration; + private Playwright playwright; + private WrappedBrowser wrappedBrowser; + private boolean isBuildNameSet = false; + private String buildName; + + public WrappedBrowser start(BrowserConfiguration configuration) { + if (disposed) { + browserConfiguration(configuration); + playwright = Playwright.create(); + disposed = false; + var executionType = Settings.web().getExecutionType(); + if (executionType.equals("regular")) { + return initializeBrowserWrapperRegularMode(); + } else { + var gridSettings = ConfigurationService.get(WebSettings.class).getGridSettings().stream().filter(g -> g.getProviderName().equals(executionType.toLowerCase())).findFirst().orElse(null); + assert gridSettings != null : String.format("The specified execution type '%s' is not declared in the configuration", executionType); + return initializeBrowserWrapperGridMode(gridSettings); + } } - case FIREFOX -> { - var browserType = playwright().firefox(); - BrowserType.LaunchOptions launchOptions = new BrowserType.LaunchOptions(); - launchOptions.setHeadless(false); - launchOptions.setTimeout(Settings.web().getArtificialDelayBeforeAction()); + else return wrappedBrowser(); + } - return browser(browserType.launch(launchOptions)); + public void close() { + if (disposed) { + return; } - case FIREFOX_HEADLESS -> { - var browserType = playwright().firefox(); - BrowserType.LaunchOptions launchOptions = new BrowserType.LaunchOptions(); - launchOptions.setHeadless(true); - - return browser(browserType.launch(launchOptions)); + if (playwright != null) { + DebugInformation.debugInfo("SHUTTING DOWN PLAYWRIGHT"); + if (wrappedBrowser() != null) { + wrappedBrowser().close(); + } + playwright = null; + if (wrappedBrowser().getGridSessionId() != null) { + RestAssured.baseURI = ConfigurationService.get(WebSettings.class).getGridSettings().stream().filter(g -> g.getProviderName().equals(Settings.web().getExecutionType().toLowerCase())).findFirst().orElse(null).getUrl(); + var response = RestAssured.given() + .delete(String.format("/session/%s", wrappedBrowser().getGridSessionId())); + } } - case EDGE -> { - var browserType = playwright().chromium(); - BrowserType.LaunchOptions launchOptions = new BrowserType.LaunchOptions(); - launchOptions.setChannel("msedge"); - launchOptions.setHeadless(false); - // launchOptions.setArgs(List.of("--log-level=3")); - // System.setProperty("webdriver.chrome.silentOutput", "true"); ? + disposed = true; + } - return browser(browserType.launch(launchOptions)); - } - case EDGE_HEADLESS -> { - var browserType = playwright().chromium(); - BrowserType.LaunchOptions launchOptions = new BrowserType.LaunchOptions(); - launchOptions.setChannel("msedge"); - launchOptions.setHeadless(true); - // launchOptions.setArgs(List.of("--log-level=3")); - // System.setProperty("webdriver.chrome.silentOutput", "true"); ? + public void restartBrowserContext() { + DebugInformation.debugInfo("RESTARTING CONTEXT"); + wrappedBrowser().changeContext(intializeBrowserContext()); + } - return browser(browserType.launch(launchOptions)); - } - case WEBKIT -> { - var browserType = playwright().webkit(); - BrowserType.LaunchOptions launchOptions = new BrowserType.LaunchOptions(); - launchOptions.setHeadless(false); - launchOptions.setTimeout(Settings.web().getArtificialDelayBeforeAction()); + private WrappedBrowser initializeBrowserWrapperRegularMode() { + wrappedBrowser(new WrappedBrowser(playwright)); + wrappedBrowser().setBrowser(initializeBrowserRegularMode()); + wrappedBrowser().setCurrentContext(intializeBrowserContext()); + wrappedBrowser().setCurrentPage(wrappedBrowser().getCurrentContext().newPage()); + return wrappedBrowser(); + } - return browser(browserType.launch(launchOptions)); - } - case WEBKIT_HEADLESS -> { - var browserType = playwright().webkit(); - BrowserType.LaunchOptions launchOptions = new BrowserType.LaunchOptions(); - launchOptions.setHeadless(true); + private WrappedBrowser initializeBrowserWrapperGridMode(GridSettings gridSettings) { + wrappedBrowser(new WrappedBrowser(playwright)); + wrappedBrowser().setBrowser(initializeBrowserGridMode(gridSettings)); + wrappedBrowser().setCurrentContext(intializeBrowserContext()); + wrappedBrowser().setCurrentPage(wrappedBrowser().getCurrentContext().newPage()); + return wrappedBrowser(); + } - return browser(browserType.launch(launchOptions)); + private Browser initializeBrowserRegularMode() { + BrowserTypes browserTypes = browserConfiguration().getBrowserTypes(); + switch (browserTypes) { + case CHROMIUM -> { + var browserType = playwright.chromium(); + BrowserType.LaunchOptions launchOptions = new BrowserType.LaunchOptions(); + launchOptions.setHeadless(false); + launchOptions.setArgs(List.of("--log-level=3", "--remote-allow-origins=*")); + launchOptions.setTimeout(Settings.web().getArtificialDelayBeforeAction()); + // System.setProperty("webdriver.chrome.silentOutput", "true"); ? + return browser(browserType.launch(launchOptions)); + } + case CHROMIUM_HEADLESS -> { + var browserType = playwright.chromium(); + BrowserType.LaunchOptions launchOptions = new BrowserType.LaunchOptions(); + launchOptions.setHeadless(true); + launchOptions.setArgs(List.of("--log-level=3")); + // System.setProperty("webdriver.chrome.silentOutput", "true"); ? + return browser(browserType.launch(launchOptions)); + } + case CHROME -> { + var browserType = playwright.chromium(); + BrowserType.LaunchOptions launchOptions = new BrowserType.LaunchOptions(); + launchOptions.setChannel("chrome"); + launchOptions.setHeadless(false); + launchOptions.setArgs(List.of("--log-level=3", "--remote-allow-origins=*")); + launchOptions.setTimeout(Settings.web().getArtificialDelayBeforeAction()); + // System.setProperty("webdriver.chrome.silentOutput", "true"); ? + return browser(browserType.launch(launchOptions)); + } + case CHROME_HEADLESS -> { + var browserType = playwright.chromium(); + BrowserType.LaunchOptions launchOptions = new BrowserType.LaunchOptions(); + launchOptions.setChannel("chrome"); + launchOptions.setHeadless(true); + launchOptions.setArgs(List.of("--log-level=3")); + // System.setProperty("webdriver.chrome.silentOutput", "true"); ? + return browser(browserType.launch(launchOptions)); + } + case FIREFOX -> { + var browserType = playwright.firefox(); + BrowserType.LaunchOptions launchOptions = new BrowserType.LaunchOptions(); + launchOptions.setHeadless(false); + launchOptions.setTimeout(Settings.web().getArtificialDelayBeforeAction()); + return browser(browserType.launch(launchOptions)); + } + case FIREFOX_HEADLESS -> { + var browserType = playwright.firefox(); + BrowserType.LaunchOptions launchOptions = new BrowserType.LaunchOptions(); + launchOptions.setHeadless(true); + return browser(browserType.launch(launchOptions)); + } + case EDGE -> { + var browserType = playwright.chromium(); + BrowserType.LaunchOptions launchOptions = new BrowserType.LaunchOptions(); + launchOptions.setChannel("msedge"); + launchOptions.setHeadless(false); + // launchOptions.setArgs(List.of("--log-level=3")); + // System.setProperty("webdriver.chrome.silentOutput", "true"); ? + return browser(browserType.launch(launchOptions)); + } + case EDGE_HEADLESS -> { + var browserType = playwright.chromium(); + BrowserType.LaunchOptions launchOptions = new BrowserType.LaunchOptions(); + launchOptions.setChannel("msedge"); + launchOptions.setHeadless(true); + // launchOptions.setArgs(List.of("--log-level=3")); + // System.setProperty("webdriver.chrome.silentOutput", "true"); ? + return browser(browserType.launch(launchOptions)); + } + case WEBKIT -> { + var browserType = playwright.webkit(); + BrowserType.LaunchOptions launchOptions = new BrowserType.LaunchOptions(); + launchOptions.setHeadless(false); + launchOptions.setTimeout(Settings.web().getArtificialDelayBeforeAction()); + return browser(browserType.launch(launchOptions)); + } + case WEBKIT_HEADLESS -> { + var browserType = playwright.webkit(); + BrowserType.LaunchOptions launchOptions = new BrowserType.LaunchOptions(); + launchOptions.setHeadless(true); + return browser(browserType.launch(launchOptions)); + } + default -> throw new IllegalArgumentException("Unsupported."); } - default -> throw new IllegalArgumentException("Unsupported."); } - } - - private static BrowserContext intializeBrowserContext() { - Browser.NewContextOptions options = getContextOptions(); - var context = browser().newContext(options); - if (Settings.web().getShouldCaptureHttpTraffic()) { - startRecordingHttpTraffic(context); + private BrowserContext intializeBrowserContext() { + Browser.NewContextOptions options = getContextOptions(); + var context = browser().newContext(options); + if (Settings.web().getShouldCaptureHttpTraffic()) { + startRecordingHttpTraffic(context); + } + return context; } - return context; - } - - // ToDo Browser Context options - private static Browser.NewContextOptions getContextOptions() { - Browser.NewContextOptions options = new Browser.NewContextOptions(); - + // ToDo Browser Context options + private Browser.NewContextOptions getContextOptions() { + Browser.NewContextOptions options = new Browser.NewContextOptions(); // if (Settings.context().isShouldSetContextSettings()) { // options.setIgnoreHTTPSErrors(Settings.context().isIgnoreHTTPSErrors()); // options.setAcceptDownloads(Settings.context().isAcceptDownloads()); @@ -252,153 +256,126 @@ private static Browser.NewContextOptions getContextOptions() { // options.setTimezoneId(Settings.context().getTimezoneId()); // options.setUserAgent(Settings.context().getUserAgent()); // } - - options.setIgnoreHTTPSErrors(true); - - // ToDo setProxy - - return options; - } - - private static void startRecordingHttpTraffic(BrowserContext context) { - Traffic.getRequestContainers().add(new Requests(context)); - context.onRequest(x -> Traffic.getContextSpecificRequests(context).add(x)); - - Traffic.getResponseContainers().add(new Responses(context)); - context.onResponse(x -> Traffic.getContextSpecificResponses(context).add(x)); - } - - private static Browser initializeBrowserGridMode(GridSettings gridSettings) { - var timeout = Settings.timeout().inMilliseconds().getConnectToRemoteGridTimeout(); - - var gridUrl = gridSettings.getUrl(); - if (gridUrl.startsWith("env_")) { - gridUrl = System.getProperty(gridSettings.getUrl()).replace("env_", ""); + options.setIgnoreHTTPSErrors(true); + // ToDo setProxy + return options; } - try { - Gson gson = new Gson(); - String serializedSettings = URLEncoder.encode(gson.toJson(gridSettings.getArguments().get(0)), "UTF-8"); - - if (gridSettings.getProviderName().equals("grid") || gridSettings.getProviderName().equals("selenoid")) { - var browserType = BROWSER_CONFIGURATION_THREAD_LOCAL.get().getBrowserTypes(); - if (browserType == BrowserTypes.FIREFOX || browserType == BrowserTypes.FIREFOX_HEADLESS || browserType == BrowserTypes.WEBKIT || browserType == BrowserTypes.WEBKIT_HEADLESS) { - throw new NotImplementedException("Playwright supports running in Selenium Grid only Chromium browsers."); - } - - RestAssured.baseURI = gridUrl; - Map capabilitiesMap = new HashMap<>(); - capabilitiesMap.put("alwaysMatch", gridSettings.getArguments().get(0)); - - Map body = new HashMap<>(); - body.put("capabilities", capabilitiesMap); - - var serializedBody = gson.toJson(body); - - var response = RestAssured.given() - .contentType(ContentType.JSON) - .body(serializedBody) - .post("/session"); - - wrappedBrowser().setGridSessionId(response.body().jsonPath().get("value.sessionId")); - - var responseBody = response.body(); - var responseJson = response.jsonPath(); - - var cdpUrl = new URI(response.jsonPath().get("value.capabilities['se:cdp']")); - cdpUrl = new URI(cdpUrl.getScheme(), cdpUrl.getUserInfo(), new URI(gridUrl).getHost(), new URI(gridUrl).getPort(), cdpUrl.getPath(), cdpUrl.getQuery(), cdpUrl.getFragment()); - - return playwright().chromium().connectOverCDP(cdpUrl.toString(), new BrowserType.ConnectOverCDPOptions().setTimeout(timeout)); - } else if (gridSettings.getProviderName().equals("lambdatest")) { - return playwright().chromium().connect(String.format("%s?capabilities=%s", gridUrl, serializedSettings), new BrowserType.ConnectOptions().setTimeout(timeout)); - } else if (gridSettings.getProviderName().equals("browserstack")) { - return playwright().chromium().connect(String.format("%s?caps=%s", gridUrl, serializedSettings), new BrowserType.ConnectOptions().setTimeout(timeout)); - } else { - throw new NotImplementedException("Unsupported grid provider. Supported are: selenium grid, selenoid, lambdatest, and browserstack."); - } - } catch (Exception e) { - DebugInformation.printStackTrace(e); - return null; + private void startRecordingHttpTraffic(BrowserContext context) { + Traffic.getRequestContainers().add(new Requests(context)); + context.onRequest(x -> Traffic.getContextSpecificRequests(context).add(x)); + Traffic.getResponseContainers().add(new Responses(context)); + context.onResponse(x -> Traffic.getContextSpecificResponses(context).add(x)); } - } - private static void changeWindowSize() { - try { - if (browserConfiguration().getHeight() != 0 && browserConfiguration().getWidth() != 0) { - wrappedBrowser().getCurrentPage().setViewportSize(browserConfiguration().getWidth(), browserConfiguration().getHeight()); + private Browser initializeBrowserGridMode(GridSettings gridSettings) { + var timeout = Settings.timeout().inMilliseconds().getConnectToRemoteGridTimeout(); + var gridUrl = gridSettings.getUrl(); + if (gridUrl.startsWith("env_")) { + gridUrl = System.getProperty(gridSettings.getUrl()).replace("env_", ""); } - } catch (Exception ignored) {} - } - - private static String getBuildName() { - if (!isBuildNameSet) { - buildName = System.getProperty("buildName"); - } - - if (buildName == null) { - InputStream input = ConfigurationService.class.getResourceAsStream("/application.properties"); - var p = new Properties(); try { - p.load(input); - } catch (IOException e) { + Gson gson = new Gson(); + String serializedSettings = URLEncoder.encode(gson.toJson(gridSettings.getArguments().get(0)), "UTF-8"); + if (gridSettings.getProviderName().equals("grid") || gridSettings.getProviderName().equals("selenoid")) { + var browserType = browserConfiguration.getBrowserTypes(); + if (browserType == BrowserTypes.FIREFOX || browserType == BrowserTypes.FIREFOX_HEADLESS || browserType == BrowserTypes.WEBKIT || browserType == BrowserTypes.WEBKIT_HEADLESS) { + throw new NotImplementedException("Playwright supports running in Selenium Grid only Chromium browsers."); + } + RestAssured.baseURI = gridUrl; + Map capabilitiesMap = new HashMap<>(); + capabilitiesMap.put("alwaysMatch", gridSettings.getArguments().get(0)); + Map body = new HashMap<>(); + body.put("capabilities", capabilitiesMap); + var serializedBody = gson.toJson(body); + var response = RestAssured.given() + .contentType(ContentType.JSON) + .body(serializedBody) + .post("/session"); + wrappedBrowser().setGridSessionId(response.body().jsonPath().get("value.sessionId")); + var responseBody = response.body(); + var responseJson = response.jsonPath(); + var cdpUrl = new URI(response.jsonPath().get("value.capabilities['se:cdp']")); + cdpUrl = new URI(cdpUrl.getScheme(), cdpUrl.getUserInfo(), new URI(gridUrl).getHost(), new URI(gridUrl).getPort(), cdpUrl.getPath(), cdpUrl.getQuery(), cdpUrl.getFragment()); + return playwright.chromium().connectOverCDP(cdpUrl.toString(), new BrowserType.ConnectOverCDPOptions().setTimeout(timeout)); + } else if (gridSettings.getProviderName().equals("lambdatest")) { + return playwright.chromium().connect(String.format("%s?capabilities=%s", gridUrl, serializedSettings), new BrowserType.ConnectOptions().setTimeout(timeout)); + } else if (gridSettings.getProviderName().equals("browserstack")) { + return playwright.chromium().connect(String.format("%s?caps=%s", gridUrl, serializedSettings), new BrowserType.ConnectOptions().setTimeout(timeout)); + } else { + throw new NotImplementedException("Unsupported grid provider. Supported are: selenium grid, selenoid, lambdatest, and browserstack."); + } + } catch (Exception e) { + DebugInformation.printStackTrace(e); return null; } + } + private void changeWindowSize() { + try { + if (browserConfiguration().getHeight() != 0 && browserConfiguration().getWidth() != 0) { + wrappedBrowser().getCurrentPage().setViewportSize(browserConfiguration().getWidth(), browserConfiguration().getHeight()); + } + } catch (Exception ignored) {} + } + + private String getBuildName() { if (!isBuildNameSet) { - buildName = p.getProperty("buildName"); + buildName = System.getProperty("buildName"); } - - if (buildName.equals("{randomNumber}") && !isBuildNameSet) { - buildName = TimestampBuilder.buildUniqueTextByPrefix("LE_"); - isBuildNameSet = true; + if (buildName == null) { + InputStream input = ConfigurationService.class.getResourceAsStream("/application.properties"); + var p = new Properties(); + try { + p.load(input); + } catch (IOException e) { + return null; + } + if (!isBuildNameSet) { + buildName = p.getProperty("buildName"); + } + if (buildName.equals("{randomNumber}") && !isBuildNameSet) { + buildName = TimestampBuilder.buildUniqueTextByPrefix("LE_"); + isBuildNameSet = true; + } } + return buildName; } - return buildName; - } - - public static BrowserConfiguration browserConfiguration() { - return BROWSER_CONFIGURATION_THREAD_LOCAL.get(); - } - - public static BrowserConfiguration browserConfiguration(BrowserConfiguration configuration) { - BROWSER_CONFIGURATION_THREAD_LOCAL.set(configuration); - return browserConfiguration(); - } - - private static Playwright playwright() { - return PLAYWRIGHT_THREAD_LOCAL.get(); - } + public BrowserConfiguration browserConfiguration() { + return browserConfiguration; + } - private static Playwright playwright(Playwright playwright) { - PLAYWRIGHT_THREAD_LOCAL.set(playwright); - return playwright(); - } + public BrowserConfiguration browserConfiguration(BrowserConfiguration configuration) { + browserConfiguration = configuration; + return browserConfiguration(); + } - public static WrappedBrowser wrappedBrowser() { - return BROWSER_WRAPPER_THREAD_LOCAL.get(); - } + public WrappedBrowser wrappedBrowser() { + return wrappedBrowser; + } - public static WrappedBrowser wrappedBrowser(WrappedBrowser wrappedBrowser) { - BROWSER_WRAPPER_THREAD_LOCAL.set(wrappedBrowser); - return BROWSER_WRAPPER_THREAD_LOCAL.get(); - } + public WrappedBrowser wrappedBrowser(WrappedBrowser wrappedBrowser) { + this.wrappedBrowser = wrappedBrowser; + return this.wrappedBrowser; + } - private static Browser browser() { - return wrappedBrowser().getBrowser(); - } + private Browser browser() { + return wrappedBrowser().getBrowser(); + } - private static Browser browser(Browser browser) { - wrappedBrowser().setBrowser(browser); - return browser(); - } + private Browser browser(Browser browser) { + wrappedBrowser().setBrowser(browser); + return browser(); + } - private static BrowserContext context() { - return wrappedBrowser().getCurrentContext(); - } + private BrowserContext context() { + return wrappedBrowser().getCurrentContext(); + } - private static BrowserContext context(BrowserContext browserContext) { - wrappedBrowser().setCurrentContext(browserContext); - return context(); + private BrowserContext context(BrowserContext browserContext) { + wrappedBrowser().setCurrentContext(browserContext); + return context(); + } } -} +} \ No newline at end of file diff --git a/bellatrix.playwright/src/main/java/solutions/bellatrix/playwright/infrastructure/WrappedBrowser.java b/bellatrix.playwright/src/main/java/solutions/bellatrix/playwright/infrastructure/WrappedBrowser.java index bbfa7877..05368fb4 100644 --- a/bellatrix.playwright/src/main/java/solutions/bellatrix/playwright/infrastructure/WrappedBrowser.java +++ b/bellatrix.playwright/src/main/java/solutions/bellatrix/playwright/infrastructure/WrappedBrowser.java @@ -45,10 +45,6 @@ public WrappedBrowser(Playwright playwright, Browser browser, BrowserContext con private String gridSessionId; public void close() { - // Close everything manually - for (var page : currentContext.pages()) page.close(); - for (var context : browser.contexts()) context.close(); - browser.close(); playwright.close(); } diff --git a/bellatrix.web/src/main/java/solutions/bellatrix/web/components/shadowdom/ShadowDomService.java b/bellatrix.web/src/main/java/solutions/bellatrix/web/components/shadowdom/ShadowDomService.java index 82dacb79..0f636194 100644 --- a/bellatrix.web/src/main/java/solutions/bellatrix/web/components/shadowdom/ShadowDomService.java +++ b/bellatrix.web/src/main/java/solutions/bellatrix/web/components/shadowdom/ShadowDomService.java @@ -110,26 +110,7 @@ private static String[] getAbsoluteCss(ShadowRoot shadowRoot, String locator) { shadowRoot.findElement(), locator, null).toArray(String[]::new); }; - if (Wait.retry(() -> { - String[] foundElements; - try { - foundElements = js.call(); - } catch (Exception e) { - throw new RuntimeException(e); - } - - if (foundElements == null || foundElements.length == 0) { - throw new IllegalArgumentException(); - } - }, Duration.ofSeconds(ConfigurationService.get(WebSettings.class).getTimeoutSettings().getElementWaitTimeout()), Duration.ofSeconds(1), false)) { - try { - return js.call(); - } catch (Exception e) { - throw new RuntimeException(e); - } - } else { - throw new IllegalArgumentException("No elements inside the shadow DOM were found with the locator: " + locator); - } + return getCss(js, locator); } private static String[] getRelativeCss(ShadowRoot shadowRoot, String locator, String parentLocator) { @@ -139,10 +120,14 @@ private static String[] getRelativeCss(ShadowRoot shadowRoot, String locator, St shadowRoot.findElement(), locator, parentLocator).toArray(String[]::new); }; + return getCss(js, locator); + } + + private static String[] getCss(Callable callable, String locator) { if (Wait.retry(() -> { String[] foundElements; try { - foundElements = js.call(); + foundElements = callable.call(); } catch (Exception e) { throw new RuntimeException(e); } @@ -152,7 +137,7 @@ private static String[] getRelativeCss(ShadowRoot shadowRoot, String locator, St } }, Duration.ofSeconds(ConfigurationService.get(WebSettings.class).getTimeoutSettings().getElementWaitTimeout()), Duration.ofSeconds(1), false)) { try { - return js.call(); + return callable.call(); } catch (Exception e) { throw new RuntimeException(e); } diff --git a/bellatrix.web/src/main/java/solutions/bellatrix/web/configuration/GridSettings.java b/bellatrix.web/src/main/java/solutions/bellatrix/web/configuration/GridSettings.java index 0760a3e3..2e03480a 100644 --- a/bellatrix.web/src/main/java/solutions/bellatrix/web/configuration/GridSettings.java +++ b/bellatrix.web/src/main/java/solutions/bellatrix/web/configuration/GridSettings.java @@ -18,10 +18,10 @@ import java.util.HashMap; import java.util.List; - +@Getter @Setter public class GridSettings { - @Getter @Setter private String providerName; - @Getter @Setter private String optionsName; - @Getter @Setter private String url; - @Getter @Setter private List> arguments; + private String providerName; + private String optionsName; + private String url; + private List> arguments; } diff --git a/bellatrix.web/src/main/java/solutions/bellatrix/web/configuration/TimeoutSettings.java b/bellatrix.web/src/main/java/solutions/bellatrix/web/configuration/TimeoutSettings.java index a57676fc..a54d1fae 100644 --- a/bellatrix.web/src/main/java/solutions/bellatrix/web/configuration/TimeoutSettings.java +++ b/bellatrix.web/src/main/java/solutions/bellatrix/web/configuration/TimeoutSettings.java @@ -15,22 +15,22 @@ import lombok.Getter; import lombok.Setter; - +@Getter @Setter public class TimeoutSettings { - @Getter @Setter private long pageLoadTimeout; - @Getter @Setter private long scriptTimeout; - @Getter @Setter private long elementWaitTimeout; - @Getter @Setter private long waitForAjaxTimeout; - @Getter @Setter private long waitUntilReadyTimeout; - @Getter @Setter private long waitForJavaScriptAnimationsTimeout; - @Getter @Setter private long waitForAngularTimeout; - @Getter @Setter private long waitForPartialUrl; - @Getter @Setter private long sleepInterval; - @Getter @Setter private long validationsTimeout; - @Getter @Setter private long elementToBeVisibleTimeout; - @Getter @Setter private long elementToExistTimeout; - @Getter @Setter private long elementToNotExistTimeout; - @Getter @Setter private long elementToBeClickableTimeout; - @Getter @Setter private long elementNotToBeVisibleTimeout; - @Getter @Setter private long elementToHaveContentTimeout; + private long pageLoadTimeout; + private long scriptTimeout; + private long elementWaitTimeout; + private long waitForAjaxTimeout; + private long waitUntilReadyTimeout; + private long waitForJavaScriptAnimationsTimeout; + private long waitForAngularTimeout; + private long waitForPartialUrl; + private long sleepInterval; + private long validationsTimeout; + private long elementToBeVisibleTimeout; + private long elementToExistTimeout; + private long elementToNotExistTimeout; + private long elementToBeClickableTimeout; + private long elementNotToBeVisibleTimeout; + private long elementToHaveContentTimeout; } diff --git a/bellatrix.web/src/main/java/solutions/bellatrix/web/configuration/UrlSettings.java b/bellatrix.web/src/main/java/solutions/bellatrix/web/configuration/UrlSettings.java index 852068c0..4add1c54 100644 --- a/bellatrix.web/src/main/java/solutions/bellatrix/web/configuration/UrlSettings.java +++ b/bellatrix.web/src/main/java/solutions/bellatrix/web/configuration/UrlSettings.java @@ -15,8 +15,8 @@ import lombok.Getter; import lombok.Setter; - +@Getter @Setter public class UrlSettings { - @Getter @Setter private String shopUrl; - @Getter @Setter private String accountUrl; + private String shopUrl; + private String accountUrl; } diff --git a/bellatrix.web/src/main/java/solutions/bellatrix/web/configuration/WebSettings.java b/bellatrix.web/src/main/java/solutions/bellatrix/web/configuration/WebSettings.java index 596561ee..d4ec8f5d 100644 --- a/bellatrix.web/src/main/java/solutions/bellatrix/web/configuration/WebSettings.java +++ b/bellatrix.web/src/main/java/solutions/bellatrix/web/configuration/WebSettings.java @@ -29,32 +29,32 @@ import java.util.ArrayList; import java.util.List; - +@Getter @Setter public class WebSettings { - @Getter @Setter private String baseUrl; - @Getter @Setter private String executionType; - @Getter @Setter private String defaultLifeCycle; - @Getter @Setter private String defaultBrowser; - @Getter @Setter private Integer defaultBrowserWidth = 0; - @Getter @Setter private Integer defaultBrowserHeight = 0; - @Getter @Setter private List gridSettings; - - @Getter @Setter private int artificialDelayBeforeAction; - @Getter @Setter private TimeoutSettings timeoutSettings; - - @Getter @Setter private Boolean automaticallyScrollToVisible; - @Getter @Setter private Boolean waitUntilReadyOnElementFound; - @Getter @Setter private Boolean waitForAngular; - @Getter @Setter private Boolean shouldHighlightElements; - @Getter @Setter private Boolean shouldCaptureHttpTraffic; - @Getter @Setter private Boolean toastNotificationBddLogging; - @Getter @Setter private long notificationToastTimeout; - - @Getter @Setter private ArrayList consoleErrorsWhitelist; - - @Getter @Setter private Boolean screenshotsOnFailEnabled; - @Getter @Setter private String screenshotsSaveLocation; - - @Getter @Setter private Boolean videosOnFailEnabled; - @Getter @Setter private String videosSaveLocation; + private String baseUrl; + private String executionType; + private String defaultLifeCycle; + private String defaultBrowser; + private Integer defaultBrowserWidth = 0; + private Integer defaultBrowserHeight = 0; + private List gridSettings; + + private int artificialDelayBeforeAction; + private TimeoutSettings timeoutSettings; + + private Boolean automaticallyScrollToVisible; + private Boolean waitUntilReadyOnElementFound; + private Boolean waitForAngular; + private Boolean shouldHighlightElements; + private Boolean shouldCaptureHttpTraffic; + private Boolean toastNotificationBddLogging; + private long notificationToastTimeout; + + private ArrayList consoleErrorsWhitelist; + + private Boolean screenshotsOnFailEnabled; + private String screenshotsSaveLocation; + + private Boolean videosOnFailEnabled; + private String videosSaveLocation; } diff --git a/bellatrix.web/src/main/java/solutions/bellatrix/web/infrastructure/DriverService.java b/bellatrix.web/src/main/java/solutions/bellatrix/web/infrastructure/DriverService.java index b6b4a388..17a8fb07 100644 --- a/bellatrix.web/src/main/java/solutions/bellatrix/web/infrastructure/DriverService.java +++ b/bellatrix.web/src/main/java/solutions/bellatrix/web/infrastructure/DriverService.java @@ -13,6 +13,7 @@ package solutions.bellatrix.web.infrastructure; +import lombok.experimental.UtilityClass; import net.lightbody.bmp.client.ClientUtil; import org.openqa.selenium.*; import org.openqa.selenium.chrome.ChromeDriver; @@ -29,10 +30,7 @@ import org.openqa.selenium.safari.SafariDriver; import org.openqa.selenium.safari.SafariOptions; import solutions.bellatrix.core.configuration.ConfigurationService; -import solutions.bellatrix.core.utilities.DebugInformation; -import solutions.bellatrix.core.utilities.Log; -import solutions.bellatrix.core.utilities.SecretsResolver; -import solutions.bellatrix.core.utilities.TimestampBuilder; +import solutions.bellatrix.core.utilities.*; import solutions.bellatrix.web.configuration.GridSettings; import solutions.bellatrix.web.configuration.WebSettings; @@ -48,469 +46,490 @@ import static io.restassured.RestAssured.given; +@UtilityClass public class DriverService { - private static final ThreadLocal DISPOSED = ThreadLocal.withInitial(() -> true); - private static final ThreadLocal BROWSER_CONFIGURATION; - private static final ThreadLocal> CUSTOM_DRIVER_OPTIONS; - private static final ThreadLocal WRAPPED_DRIVER; - private static boolean isBuildNameSet = false; - private static String buildName; + private static ThreadLocal DRIVER_MANAGER = new ThreadLocal(); static { - CUSTOM_DRIVER_OPTIONS = new ThreadLocal<>(); - CUSTOM_DRIVER_OPTIONS.set(new HashMap<>()); - BROWSER_CONFIGURATION = new ThreadLocal<>(); - WRAPPED_DRIVER = new ThreadLocal<>(); + var driverManager = new DriverManager(); + SingletonFactory.register(driverManager); + ShutdownManager.register(driverManager::close); + DRIVER_MANAGER.set(driverManager); } - public static HashMap getCustomDriverOptions() { - return CUSTOM_DRIVER_OPTIONS.get(); + public static Map getCustomDriverOptions() { + return DRIVER_MANAGER.get().customDriverOptions; } public static void addDriverOptions(String key, String value) { - CUSTOM_DRIVER_OPTIONS.get().put(key, value); + DRIVER_MANAGER.get().addDriverOptions(key, value); } public static WebDriver getWrappedDriver() { - return WRAPPED_DRIVER.get(); + return DRIVER_MANAGER.get().wrapppedDriver; } public static void setWrappedDriver(WebDriver driver) { - WRAPPED_DRIVER.set(driver); + DRIVER_MANAGER.get().wrapppedDriver = driver; } public static BrowserConfiguration getBrowserConfiguration() { - return BROWSER_CONFIGURATION.get(); + return DRIVER_MANAGER.get().browserConfiguration; } public static WebDriver start(BrowserConfiguration configuration) { - if (DISPOSED.get()) { - BROWSER_CONFIGURATION.set(configuration); - DISPOSED.set(false); - WebDriver driver; - var webSettings = ConfigurationService.get(WebSettings.class); - var executionType = webSettings.getExecutionType(); - if (executionType.equals("regular")) { - driver = initializeDriverRegularMode(); - } else if (executionType.equals("grid") || executionType.equals("selenoid")) { - var gridSettings = webSettings.getGridSettings().stream().filter(g -> g.getProviderName().equals(executionType.toLowerCase())).findFirst(); - assert gridSettings.isPresent() : String.format("The specified execution type '%s' is not declared in the configuration", executionType); - driver = initializeDriverGridMode(gridSettings.get()); - } else if (executionType.equals("healenium")) { - var gridSettings = webSettings.getGridSettings().stream().filter(g -> g.getProviderName().equals(executionType.toLowerCase())).findFirst(); - assert gridSettings.isPresent() : String.format("The specified execution type '%s' is not declared in the configuration", executionType); - driver = initializeDriverGridMode(gridSettings.get()); - } else { - var gridSettings = webSettings.getGridSettings().stream().filter(g -> g.getProviderName().equals(executionType.toLowerCase())).findFirst(); - assert gridSettings.isPresent() : String.format("The specified execution type '%s' is not declared in the configuration", executionType); - driver = initializeDriverCloudGridMode(gridSettings.get()); - } - - driver.manage().timeouts().pageLoadTimeout(Duration.ofSeconds(ConfigurationService.get(WebSettings.class).getTimeoutSettings().getPageLoadTimeout())); - driver.manage().timeouts().scriptTimeout(Duration.ofSeconds(ConfigurationService.get(WebSettings.class).getTimeoutSettings().getScriptTimeout())); - - if(getBrowserConfiguration().getHeight() != 0 && getBrowserConfiguration().getWidth() != 0) { - changeWindowSize(driver); - } - else { - driver.manage().window().maximize(); - } - - Log.info(String.format("Window resized to dimensions: %s", driver.manage().window().getSize().toString())); - WRAPPED_DRIVER.set(driver); - - return driver; - } else return WRAPPED_DRIVER.get(); + return DRIVER_MANAGER.get().start(configuration); } - private static WebDriver initializeDriverCloudGridMode(GridSettings gridSettings) { - MutableCapabilities caps = new MutableCapabilities(); + public static void close() { + DRIVER_MANAGER.get().close(); + } - switch (BROWSER_CONFIGURATION.get().getBrowser()) { - case CHROME_HEADLESS: - case CHROME: { - var chromeOptions = new ChromeOptions(); - caps.setCapability(ChromeOptions.CAPABILITY, chromeOptions); - break; - } - case FIREFOX_HEADLESS: - case FIREFOX: { - var firefoxOptions = new FirefoxOptions(); - caps.setCapability(ChromeOptions.CAPABILITY, firefoxOptions); - break; - } - case EDGE_HEADLESS: - case EDGE: { - var edgeOptions = new EdgeOptions(); - caps.setCapability(ChromeOptions.CAPABILITY, edgeOptions); - break; - } - case SAFARI: { - var safariOptions = new SafariOptions(); - caps.setCapability(ChromeOptions.CAPABILITY, safariOptions); - break; - } + private static class DriverManager { + private DriverManager() { } - HashMap options = new HashMap(); + private boolean disposed = true; + private BrowserConfiguration browserConfiguration; + private final Map customDriverOptions = new HashMap<>(); + private WebDriver wrapppedDriver; + private boolean isBuildNameSet; + private String buildName; + + public void addDriverOptions(String key, String value) { + customDriverOptions.put(key, value); + } - // Anton: maybe this is something else for other clouds, should be tested. - // If this is the case, we need to have branching per provider name. - options.put("sessionName", getBrowserConfiguration().getTestName()); - // if (gridSettings.getProviderName() == "browserstack") { - // options.put("sessionName", getBrowserConfiguration().getTestName()); - // } + public WebDriver start(BrowserConfiguration configuration) { + if (disposed) { + browserConfiguration = configuration; + disposed = false; + WebDriver driver; + var webSettings = ConfigurationService.get(WebSettings.class); + var executionType = webSettings.getExecutionType(); + if (executionType.equals("regular")) { + driver = initializeDriverRegularMode(); + } else if (executionType.equals("grid") || executionType.equals("selenoid")) { + var gridSettings = webSettings.getGridSettings().stream().filter(g -> g.getProviderName().equals(executionType.toLowerCase())).findFirst(); + assert gridSettings.isPresent() : String.format("The specified execution type '%s' is not declared in the configuration", executionType); + driver = initializeDriverGridMode(gridSettings.get()); + } else if (executionType.equals("healenium")) { + var gridSettings = webSettings.getGridSettings().stream().filter(g -> g.getProviderName().equals(executionType.toLowerCase())).findFirst(); + assert gridSettings.isPresent() : String.format("The specified execution type '%s' is not declared in the configuration", executionType); + driver = initializeDriverGridMode(gridSettings.get()); + } else { + var gridSettings = webSettings.getGridSettings().stream().filter(g -> g.getProviderName().equals(executionType.toLowerCase())).findFirst(); + assert gridSettings.isPresent() : String.format("The specified execution type '%s' is not declared in the configuration", executionType); + driver = initializeDriverCloudGridMode(gridSettings.get()); + } - addGridOptions(options, gridSettings); + driver.manage().timeouts().pageLoadTimeout(Duration.ofSeconds(ConfigurationService.get(WebSettings.class).getTimeoutSettings().getPageLoadTimeout())); + driver.manage().timeouts().scriptTimeout(Duration.ofSeconds(ConfigurationService.get(WebSettings.class).getTimeoutSettings().getScriptTimeout())); - caps.setCapability(gridSettings.getOptionsName(), options); - WebDriver driver = null; - try { - var url = getUrl(gridSettings.getUrl()); - driver = new RemoteWebDriver(new URI(url).toURL(), caps); - } catch (Exception e) { - DebugInformation.printStackTrace(e); - } + if(getBrowserConfiguration().getHeight() != 0 && getBrowserConfiguration().getWidth() != 0) { + changeWindowSize(driver); + } + else { + driver.manage().window().maximize(); + } - return driver; - } + Log.info(String.format("Window resized to dimensions: %s", driver.manage().window().getSize().toString())); + wrapppedDriver = driver; - private static WebDriver initializeDriverGridMode(GridSettings gridSettings) { - var caps = new DesiredCapabilities(); - if (BROWSER_CONFIGURATION.get().getPlatform() != Platform.ANY) { - caps.setCapability("platform", BROWSER_CONFIGURATION.get().getPlatform()); + return driver; + } else + return wrapppedDriver; } - if (BROWSER_CONFIGURATION.get().getVersion() != 0) { - caps.setCapability("version", BROWSER_CONFIGURATION.get().getVersion()); - } else { - caps.setCapability("version", "latest"); - } + private WebDriver initializeDriverCloudGridMode(GridSettings gridSettings) { + MutableCapabilities caps = new MutableCapabilities(); - switch (BROWSER_CONFIGURATION.get().getBrowser()) { - case CHROME_HEADLESS: - case CHROME: { - var chromeOptions = new ChromeOptions(); - addGridOptions(chromeOptions, gridSettings); - caps.setCapability(ChromeOptions.CAPABILITY, chromeOptions); - break; - } - case FIREFOX_HEADLESS: - case FIREFOX: { - var firefoxOptions = new FirefoxOptions(); - addGridOptions(firefoxOptions, gridSettings); - caps.setCapability(ChromeOptions.CAPABILITY, firefoxOptions); - break; - } - case EDGE_HEADLESS: - case EDGE: { - var edgeOptions = new EdgeOptions(); - addGridOptions(edgeOptions, gridSettings); - caps.setCapability(ChromeOptions.CAPABILITY, edgeOptions); - break; - } - case SAFARI: { - var safariOptions = new SafariOptions(); - addGridOptions(safariOptions, gridSettings); - caps.setCapability(ChromeOptions.CAPABILITY, safariOptions); - break; - } - case INTERNET_EXPLORER: { - var ieOptions = new InternetExplorerOptions(); - addGridOptions(ieOptions, gridSettings); - caps.setCapability(ChromeOptions.CAPABILITY, ieOptions); - break; + switch (browserConfiguration.getBrowser()) { + case CHROME_HEADLESS: + case CHROME: { + var chromeOptions = new ChromeOptions(); + caps.setCapability(ChromeOptions.CAPABILITY, chromeOptions); + break; + } + case FIREFOX_HEADLESS: + case FIREFOX: { + var firefoxOptions = new FirefoxOptions(); + caps.setCapability(ChromeOptions.CAPABILITY, firefoxOptions); + break; + } + case EDGE_HEADLESS: + case EDGE: { + var edgeOptions = new EdgeOptions(); + caps.setCapability(ChromeOptions.CAPABILITY, edgeOptions); + break; + } + case SAFARI: { + var safariOptions = new SafariOptions(); + caps.setCapability(ChromeOptions.CAPABILITY, safariOptions); + break; + } } - } - WebDriver driver = null; - try { - var gridUrl = gridSettings.getUrl(); - var url = getUrl(gridUrl); + HashMap options = new HashMap(); - driver = new RemoteWebDriver(new URI(url).toURL(), caps); - } catch (MalformedURLException | URISyntaxException e) { - DebugInformation.printStackTrace(e); - } + // Anton: maybe this is something else for other clouds, should be tested. + // If this is the case, we need to have branching per provider name. + options.put("sessionName", getBrowserConfiguration().getTestName()); + // if (gridSettings.getProviderName() == "browserstack") { + // options.put("sessionName", getBrowserConfiguration().getTestName()); + // } - return driver; - } + addGridOptions(options, gridSettings); - private static WebDriver initializeDriverRegularMode() { - WebDriver driver = null; - boolean shouldCaptureHttpTraffic = ConfigurationService.get(WebSettings.class).getShouldCaptureHttpTraffic(); + caps.setCapability(gridSettings.getOptionsName(), options); + WebDriver driver = null; + try { + var url = getUrl(gridSettings.getUrl()); + driver = new RemoteWebDriver(new URI(url).toURL(), caps); + } catch (Exception e) { + DebugInformation.printStackTrace(e); + } - Proxy proxyConfig = null; - if (shouldCaptureHttpTraffic) { - ProxyServer.init(); - proxyConfig = ClientUtil.createSeleniumProxy(ProxyServer.get()); - ProxyServer.newHar(); + return driver; } - switch (BROWSER_CONFIGURATION.get().getBrowser()) { - case CHROME -> { - var chromeOptions = new ChromeOptions(); - addDriverOptions(chromeOptions); - addDriverCapabilities(chromeOptions); - chromeOptions.addArguments("--log-level=3","--remote-allow-origins=*", "--disable-search-engine-choice-screen"); - chromeOptions.setAcceptInsecureCerts(true); - chromeOptions.setCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR, UnexpectedAlertBehaviour.ACCEPT); - System.setProperty("webdriver.chrome.silentOutput", "true"); - if (shouldCaptureHttpTraffic) { - chromeOptions.setProxy(proxyConfig); - } - - driver = new ChromeDriver(chromeOptions); + private WebDriver initializeDriverGridMode(GridSettings gridSettings) { + var caps = new DesiredCapabilities(); + if (browserConfiguration.getPlatform() != Platform.ANY) { + caps.setCapability("platform", browserConfiguration.getPlatform()); } - case CHROME_HEADLESS -> { - var chromeHeadlessOptions = new ChromeOptions(); - addDriverOptions(chromeHeadlessOptions); - chromeHeadlessOptions.setAcceptInsecureCerts(true); - chromeHeadlessOptions.addArguments("--log-level=3","--remote-allow-origins=*", "--disable-search-engine-choice-screen"); - chromeHeadlessOptions.setCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR, UnexpectedAlertBehaviour.ACCEPT); - chromeHeadlessOptions.addArguments("--headless=old"); - System.setProperty("webdriver.chrome.silentOutput", "true"); - if (shouldCaptureHttpTraffic) chromeHeadlessOptions.setProxy(proxyConfig); - - driver = new ChromeDriver(chromeHeadlessOptions); - } - case CHROME_MOBILE -> { - var chromeHeadlessOptions = new ChromeOptions(); - addDriverOptions(chromeHeadlessOptions); - chromeHeadlessOptions.setAcceptInsecureCerts(true); - chromeHeadlessOptions.addArguments("--log-level=3","--remote-allow-origins=*", "--disable-search-engine-choice-screen"); - chromeHeadlessOptions.setCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR, UnexpectedAlertBehaviour.ACCEPT); - - Map deviceMetrics = new HashMap<>(); - deviceMetrics.put("width", BROWSER_CONFIGURATION.get().getDeviceName().getWidth()); - deviceMetrics.put("height", BROWSER_CONFIGURATION.get().getDeviceName().getHeight()); - deviceMetrics.put("pixelRatio", BROWSER_CONFIGURATION.get().getDeviceName().getScaleFactor()); - - Map mobileEmulation = new HashMap<>(); - mobileEmulation.put("deviceMetrics", deviceMetrics); - mobileEmulation.put("userAgent", "Mozilla/5.0 (Linux; Android 4.2.1; en-us; Nexus 5 Build/JOP40D) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Mobile Safari/535.19"); - - chromeHeadlessOptions.setExperimentalOption("mobileEmulation", mobileEmulation); - System.setProperty("webdriver.chrome.silentOutput", "true"); - if (shouldCaptureHttpTraffic) chromeHeadlessOptions.setProxy(proxyConfig); - - driver = new TouchableWebDriver(chromeHeadlessOptions); - } - case FIREFOX -> { - var firefoxOptions = new FirefoxOptions(); - addDriverOptions(firefoxOptions); - firefoxOptions.setAcceptInsecureCerts(true); - if (shouldCaptureHttpTraffic) firefoxOptions.setProxy(proxyConfig); - driver = new FirefoxDriver(firefoxOptions); - } - case FIREFOX_HEADLESS -> { - var firefoxHeadlessOptions = new FirefoxOptions(); - addDriverOptions(firefoxHeadlessOptions); - firefoxHeadlessOptions.setAcceptInsecureCerts(true); - firefoxHeadlessOptions.addArguments("--headless"); - if (shouldCaptureHttpTraffic) firefoxHeadlessOptions.setProxy(proxyConfig); - driver = new FirefoxDriver(firefoxHeadlessOptions); - } - case EDGE -> { - var edgeOptions = new EdgeOptions(); - addDriverOptions(edgeOptions); - if (shouldCaptureHttpTraffic) edgeOptions.setProxy(proxyConfig); - driver = new EdgeDriver(edgeOptions); - } - case EDGE_HEADLESS -> { - var edgeOptions = new EdgeOptions(); - edgeOptions.addArguments("--headless"); - edgeOptions.addArguments("--disable-gpu"); - addDriverOptions(edgeOptions); - if (shouldCaptureHttpTraffic) edgeOptions.setProxy(proxyConfig); - driver = new EdgeDriver(edgeOptions); + + if (browserConfiguration.getVersion() != 0) { + caps.setCapability("version", browserConfiguration.getVersion()); + } else { + caps.setCapability("version", "latest"); } - case SAFARI -> { - System.setProperty("webdriver.safari.driver", "/usr/bin/safaridriver"); - var safariOptions = new SafariOptions(); - addDriverOptions(safariOptions); - if (shouldCaptureHttpTraffic) safariOptions.setProxy(proxyConfig); - driver = new SafariDriver(safariOptions); + + switch (browserConfiguration.getBrowser()) { + case CHROME_HEADLESS: + case CHROME: { + var chromeOptions = new ChromeOptions(); + addGridOptions(chromeOptions, gridSettings); + caps.setCapability(ChromeOptions.CAPABILITY, chromeOptions); + break; + } + case FIREFOX_HEADLESS: + case FIREFOX: { + var firefoxOptions = new FirefoxOptions(); + addGridOptions(firefoxOptions, gridSettings); + caps.setCapability(ChromeOptions.CAPABILITY, firefoxOptions); + break; + } + case EDGE_HEADLESS: + case EDGE: { + var edgeOptions = new EdgeOptions(); + addGridOptions(edgeOptions, gridSettings); + caps.setCapability(ChromeOptions.CAPABILITY, edgeOptions); + break; + } + case SAFARI: { + var safariOptions = new SafariOptions(); + addGridOptions(safariOptions, gridSettings); + caps.setCapability(ChromeOptions.CAPABILITY, safariOptions); + break; + } + case INTERNET_EXPLORER: { + var ieOptions = new InternetExplorerOptions(); + addGridOptions(ieOptions, gridSettings); + caps.setCapability(ChromeOptions.CAPABILITY, ieOptions); + break; + } } - case INTERNET_EXPLORER -> { - var internetExplorerOptions = new InternetExplorerOptions(); - addDriverOptions(internetExplorerOptions); - internetExplorerOptions.introduceFlakinessByIgnoringSecurityDomains().ignoreZoomSettings(); - if (shouldCaptureHttpTraffic) internetExplorerOptions.setProxy(proxyConfig); - driver = new InternetExplorerDriver(internetExplorerOptions); + + WebDriver driver = null; + try { + var gridUrl = gridSettings.getUrl(); + var url = getUrl(gridUrl); + + driver = new RemoteWebDriver(new URI(url).toURL(), caps); + } catch (MalformedURLException | URISyntaxException e) { + DebugInformation.printStackTrace(e); } + + return driver; } - return driver; - } + private WebDriver initializeDriverRegularMode() { + WebDriver driver = null; + boolean shouldCaptureHttpTraffic = ConfigurationService.get(WebSettings.class).getShouldCaptureHttpTraffic(); - private static DesiredCapabilities addDriverCapabilities(ChromeOptions chromeOptions) { - DesiredCapabilities caps = new DesiredCapabilities(); - // INIT CHROME OPTIONS - Map prefs = new HashMap(); - Map profile = new HashMap(); - Map contentSettings = new HashMap(); - - // SET CHROME OPTIONS - // 0 - Default, 1 - Allow, 2 - Block - contentSettings.put("notifications", 1); - profile.put("managed_default_content_settings", contentSettings); - prefs.put("profile", profile); - chromeOptions.setExperimentalOption("prefs", prefs); - - // SET CAPABILITY - caps.setCapability(ChromeOptions.CAPABILITY, chromeOptions); - return caps; - } + Proxy proxyConfig = null; + if (shouldCaptureHttpTraffic) { + ProxyServer.init(); + proxyConfig = ClientUtil.createSeleniumProxy(ProxyServer.get()); + ProxyServer.newHar(); + } - private static void addGridOptions(HashMap options, GridSettings gridSettings) { - Log.info("Add WebDriver Options:"); - Log.info(""); - for (var entry : gridSettings.getArguments()) { - for (var c : entry.entrySet()) { - if (c.getKey().toLowerCase().contains("build")) { - var buildName = getBuildName(); - if (buildName == null) { - buildName = c.getValue().toString(); + switch (browserConfiguration.getBrowser()) { + case CHROME -> { + var chromeOptions = new ChromeOptions(); + addDriverOptions(chromeOptions); + addDriverCapabilities(chromeOptions); + chromeOptions.addArguments("--log-level=3","--remote-allow-origins=*", "--disable-search-engine-choice-screen"); + chromeOptions.setAcceptInsecureCerts(true); + chromeOptions.setCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR, UnexpectedAlertBehaviour.ACCEPT); + System.setProperty("webdriver.chrome.silentOutput", "true"); + if (shouldCaptureHttpTraffic) { + chromeOptions.setProxy(proxyConfig); } - options.put(c.getKey(), buildName); - Log.info(c.getKey() + " = " + buildName); - } else { - if (c.getValue() instanceof String && c.getValue().toString().startsWith("{env_")) { - var envValue = SecretsResolver.getSecret(c.getValue().toString()); - options.put(c.getKey(), envValue); - Log.info(c.getKey() + " = " + envValue); - } else { - options.put(c.getKey(), c.getValue()); - Log.info(c.getKey() + " = " + c.getValue()); - } + driver = new ChromeDriver(chromeOptions); + } + case CHROME_HEADLESS -> { + var chromeHeadlessOptions = new ChromeOptions(); + addDriverOptions(chromeHeadlessOptions); + chromeHeadlessOptions.setAcceptInsecureCerts(true); + chromeHeadlessOptions.addArguments("--log-level=3","--remote-allow-origins=*", "--disable-search-engine-choice-screen"); + chromeHeadlessOptions.setCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR, UnexpectedAlertBehaviour.ACCEPT); + chromeHeadlessOptions.addArguments("--headless=old"); + System.setProperty("webdriver.chrome.silentOutput", "true"); + if (shouldCaptureHttpTraffic) chromeHeadlessOptions.setProxy(proxyConfig); + + driver = new ChromeDriver(chromeHeadlessOptions); + } + case CHROME_MOBILE -> { + var chromeHeadlessOptions = new ChromeOptions(); + addDriverOptions(chromeHeadlessOptions); + chromeHeadlessOptions.setAcceptInsecureCerts(true); + chromeHeadlessOptions.addArguments("--log-level=3","--remote-allow-origins=*", "--disable-search-engine-choice-screen"); + chromeHeadlessOptions.setCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR, UnexpectedAlertBehaviour.ACCEPT); + + Map deviceMetrics = new HashMap<>(); + deviceMetrics.put("width", browserConfiguration.getDeviceName().getWidth()); + deviceMetrics.put("height", browserConfiguration.getDeviceName().getHeight()); + deviceMetrics.put("pixelRatio", browserConfiguration.getDeviceName().getScaleFactor()); + + Map mobileEmulation = new HashMap<>(); + mobileEmulation.put("deviceMetrics", deviceMetrics); + mobileEmulation.put("userAgent", "Mozilla/5.0 (Linux; Android 4.2.1; en-us; Nexus 5 Build/JOP40D) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Mobile Safari/535.19"); + + chromeHeadlessOptions.setExperimentalOption("mobileEmulation", mobileEmulation); + System.setProperty("webdriver.chrome.silentOutput", "true"); + if (shouldCaptureHttpTraffic) chromeHeadlessOptions.setProxy(proxyConfig); + + driver = new TouchableWebDriver(chromeHeadlessOptions); + } + case FIREFOX -> { + var firefoxOptions = new FirefoxOptions(); + addDriverOptions(firefoxOptions); + firefoxOptions.setAcceptInsecureCerts(true); + if (shouldCaptureHttpTraffic) firefoxOptions.setProxy(proxyConfig); + driver = new FirefoxDriver(firefoxOptions); + } + case FIREFOX_HEADLESS -> { + var firefoxHeadlessOptions = new FirefoxOptions(); + addDriverOptions(firefoxHeadlessOptions); + firefoxHeadlessOptions.setAcceptInsecureCerts(true); + firefoxHeadlessOptions.addArguments("--headless"); + if (shouldCaptureHttpTraffic) firefoxHeadlessOptions.setProxy(proxyConfig); + driver = new FirefoxDriver(firefoxHeadlessOptions); + } + case EDGE -> { + var edgeOptions = new EdgeOptions(); + addDriverOptions(edgeOptions); + if (shouldCaptureHttpTraffic) edgeOptions.setProxy(proxyConfig); + driver = new EdgeDriver(edgeOptions); + } + case EDGE_HEADLESS -> { + var edgeOptions = new EdgeOptions(); + edgeOptions.addArguments("--headless"); + edgeOptions.addArguments("--disable-gpu"); + addDriverOptions(edgeOptions); + if (shouldCaptureHttpTraffic) edgeOptions.setProxy(proxyConfig); + driver = new EdgeDriver(edgeOptions); + } + case SAFARI -> { + System.setProperty("webdriver.safari.driver", "/usr/bin/safaridriver"); + var safariOptions = new SafariOptions(); + addDriverOptions(safariOptions); + if (shouldCaptureHttpTraffic) safariOptions.setProxy(proxyConfig); + driver = new SafariDriver(safariOptions); + } + case INTERNET_EXPLORER -> { + var internetExplorerOptions = new InternetExplorerOptions(); + addDriverOptions(internetExplorerOptions); + internetExplorerOptions.introduceFlakinessByIgnoringSecurityDomains().ignoreZoomSettings(); + if (shouldCaptureHttpTraffic) internetExplorerOptions.setProxy(proxyConfig); + driver = new InternetExplorerDriver(internetExplorerOptions); } } - if ("lambdatest".equalsIgnoreCase(gridSettings.getProviderName())) { - options.put("lambdaMaskCommands", new String[]{"setValues", "setCookies", "getCookies"}); - - try { - var usernameSecret = gridSettings.getArguments().get(0).get("username").toString(); - var accessKeySecret = gridSettings.getArguments().get(0).get("accessKey").toString(); - var usernameValue = SecretsResolver.getSecret(usernameSecret); - var accessKeyValue = SecretsResolver.getSecret(accessKeySecret); + return driver; + } - var res = given().auth().preemptive().basic(usernameValue, accessKeyValue) - .get("https://api.lambdatest.com/automation/api/v1/user-files"); + private DesiredCapabilities addDriverCapabilities(ChromeOptions chromeOptions) { + DesiredCapabilities caps = new DesiredCapabilities(); + // INIT CHROME OPTIONS + Map prefs = new HashMap(); + Map profile = new HashMap(); + Map contentSettings = new HashMap(); + + // SET CHROME OPTIONS + // 0 - Default, 1 - Allow, 2 - Block + contentSettings.put("notifications", 1); + profile.put("managed_default_content_settings", contentSettings); + prefs.put("profile", profile); + chromeOptions.setExperimentalOption("prefs", prefs); + + // SET CAPABILITY + caps.setCapability(ChromeOptions.CAPABILITY, chromeOptions); + return caps; + } - options.put("lambda:userFiles", res.body().jsonPath().getList("data.key")); - } catch (Exception e) { - DebugInformation.printStackTrace(e); + private void addGridOptions(HashMap options, GridSettings gridSettings) { + Log.info("Add WebDriver Options:"); + Log.info(""); + for (var entry : gridSettings.getArguments()) { + for (var c : entry.entrySet()) { + if (c.getKey().toLowerCase().contains("build")) { + var buildName = getBuildName(); + if (buildName == null) { + buildName = c.getValue().toString(); + } + + options.put(c.getKey(), buildName); + Log.info(c.getKey() + " = " + buildName); + } else { + if (c.getValue() instanceof String && c.getValue().toString().startsWith("{env_")) { + var envValue = SecretsResolver.getSecret(c.getValue().toString()); + options.put(c.getKey(), envValue); + Log.info(c.getKey() + " = " + envValue); + } else { + options.put(c.getKey(), c.getValue()); + Log.info(c.getKey() + " = " + c.getValue()); + } + } } + if ("lambdatest".equalsIgnoreCase(gridSettings.getProviderName())) { + options.put("lambdaMaskCommands", new String[]{"setValues", "setCookies", "getCookies"}); - } + try { + var usernameSecret = gridSettings.getArguments().get(0).get("username").toString(); + var accessKeySecret = gridSettings.getArguments().get(0).get("accessKey").toString(); + var usernameValue = SecretsResolver.getSecret(usernameSecret); + var accessKeyValue = SecretsResolver.getSecret(accessKeySecret); + + var res = given().auth().preemptive().basic(usernameValue, accessKeyValue) + .get("https://api.lambdatest.com/automation/api/v1/user-files"); + + options.put("lambda:userFiles", res.body().jsonPath().getList("data.key")); + } catch (Exception e) { + DebugInformation.printStackTrace(e); + } - Log.info(""); - } - } - private static void addGridOptions(TOption options, GridSettings gridSettings) { - for (var entry : gridSettings.getArguments()) { - for (var c : entry.entrySet()) { - if (c.getValue() instanceof String && c.getValue().toString().startsWith("{env_")) { - var envValue = SecretsResolver.getSecret(c.getValue().toString()); - options.setCapability(c.getKey(), envValue); - } else { - options.setCapability(c.getKey(), c.getValue()); } + + Log.info(""); } } - if ("lambdatest".equalsIgnoreCase(gridSettings.getProviderName())) { - options.setCapability("lambdaMaskCommands", new String[]{"setValues", "setCookies", "getCookies"}); - } - } + private void addGridOptions(TOption options, GridSettings gridSettings) { + for (var entry : gridSettings.getArguments()) { + for (var c : entry.entrySet()) { + if (c.getValue() instanceof String && c.getValue().toString().startsWith("{env_")) { + var envValue = SecretsResolver.getSecret(c.getValue().toString()); + options.setCapability(c.getKey(), envValue); + } else { + options.setCapability(c.getKey(), c.getValue()); + } + } + } - private static void addDriverOptions(TOption chromeOptions) { - for (var optionKey : BROWSER_CONFIGURATION.get().driverOptions.keySet()) { - chromeOptions.setCapability(optionKey, BROWSER_CONFIGURATION.get().driverOptions.get(optionKey)); + if ("lambdatest".equalsIgnoreCase(gridSettings.getProviderName())) { + options.setCapability("lambdaMaskCommands", new String[]{"setValues", "setCookies", "getCookies"}); + } } - } - private static void changeWindowSize(WebDriver wrappedDriver) { - try { - if (getBrowserConfiguration().getHeight() != 0 && getBrowserConfiguration().getWidth() != 0) { - Log.info(String.format("Setting window size to %sx%s",getBrowserConfiguration().getWidth(), getBrowserConfiguration().getHeight())); - wrappedDriver.manage().window().setSize(new Dimension(getBrowserConfiguration().getWidth(), getBrowserConfiguration().getHeight())); + private void addDriverOptions(TOption chromeOptions) { + for (var optionKey : browserConfiguration.driverOptions.keySet()) { + chromeOptions.setCapability(optionKey, browserConfiguration.driverOptions.get(optionKey)); } - } catch (Exception ex) { System.out.println("Error while resizing browser window: " + ex.getMessage());} - } - - private static String getBuildName() { - if (!isBuildNameSet) { - buildName = System.getProperty("buildName"); } - if (buildName == null) { - InputStream input = ConfigurationService.class.getResourceAsStream("/application.properties"); - var p = new Properties(); + private void changeWindowSize(WebDriver wrappedDriver) { try { - p.load(input); - } catch (IOException e) { - return null; - } + if (getBrowserConfiguration().getHeight() != 0 && getBrowserConfiguration().getWidth() != 0) { + Log.info(String.format("Setting window size to %sx%s",getBrowserConfiguration().getWidth(), getBrowserConfiguration().getHeight())); + wrappedDriver.manage().window().setSize(new Dimension(getBrowserConfiguration().getWidth(), getBrowserConfiguration().getHeight())); + } + } catch (Exception ex) { System.out.println("Error while resizing browser window: " + ex.getMessage());} + } + private String getBuildName() { if (!isBuildNameSet) { - buildName = p.getProperty("buildName"); + buildName = System.getProperty("buildName"); } - if (buildName.equals("{randomNumber}") && !isBuildNameSet) { - buildName = TimestampBuilder.buildUniqueTextByPrefix("LE_"); - isBuildNameSet = true; + if (buildName == null) { + InputStream input = ConfigurationService.class.getResourceAsStream("/application.properties"); + var p = new Properties(); + try { + p.load(input); + } catch (IOException e) { + return null; + } + + if (!isBuildNameSet) { + buildName = p.getProperty("buildName"); + } + + if (buildName.equals("{randomNumber}") && !isBuildNameSet) { + buildName = TimestampBuilder.buildUniqueTextByPrefix("LE_"); + isBuildNameSet = true; + } } + + return buildName; } - return buildName; - } + private String getUrl(String url) { + String result = url; + if (url.startsWith("{env_")) { + result = SecretsResolver.getSecret(url); + } else if (url.contains("{env_")) { + String pattern = "\\{env_.*?\\}"; + Pattern compiledPattern = Pattern.compile(pattern); + Matcher matcher = compiledPattern.matcher(url); + List allMatches = new ArrayList(); + + while (matcher.find()) { + allMatches.add(matcher.group()); + } - private static String getUrl(String url) { - String result = url; - if (url.startsWith("{env_")) { - result = SecretsResolver.getSecret(url); - } else if (url.contains("{env_")) { - String pattern = "\\{env_.*?\\}"; - Pattern compiledPattern = Pattern.compile(pattern); - Matcher matcher = compiledPattern.matcher(url); - List allMatches = new ArrayList(); - - while (matcher.find()) { - allMatches.add(matcher.group()); + for (String match : allMatches) { + result = result.replace(match, SecretsResolver.getSecret(match)); + } } - for (String match : allMatches) { - result = result.replace(match, SecretsResolver.getSecret(match)); - } + return result; } - return result; - } + public void close() { + if (disposed) { + return; + } - public static void close() { - if (DISPOSED.get()) { - return; - } + if (wrapppedDriver != null) { + DebugInformation.debugInfo("SHUTTING DOWN WRAPPED_DRIVER"); + wrapppedDriver.quit(); + if (customDriverOptions != null) { + customDriverOptions.clear(); + } + } - if (WRAPPED_DRIVER.get() != null) { - DebugInformation.debugInfo("SHUTTING DOWN WRAPPED_DRIVER"); - WRAPPED_DRIVER.get().quit(); - if (CUSTOM_DRIVER_OPTIONS.get() != null) { - CUSTOM_DRIVER_OPTIONS.get().clear(); + boolean shouldCaptureHttpTraffic = ConfigurationService.get(WebSettings.class).getShouldCaptureHttpTraffic(); + if (shouldCaptureHttpTraffic) { + ProxyServer.close(); } - } - boolean shouldCaptureHttpTraffic = ConfigurationService.get(WebSettings.class).getShouldCaptureHttpTraffic(); - if (shouldCaptureHttpTraffic) { - ProxyServer.close(); + disposed = true; } - - DISPOSED.set(true); } } \ No newline at end of file diff --git a/bellatrix.web/src/main/java/solutions/bellatrix/web/services/ComponentCreateService.java b/bellatrix.web/src/main/java/solutions/bellatrix/web/services/ComponentCreateService.java index 211755eb..214e1ab4 100644 --- a/bellatrix.web/src/main/java/solutions/bellatrix/web/services/ComponentCreateService.java +++ b/bellatrix.web/src/main/java/solutions/bellatrix/web/services/ComponentCreateService.java @@ -159,7 +159,7 @@ public TCo } public List allBy(Class componentClass, TFindStrategy findStrategy) { - var nativeElements = DriverService.getWrappedDriver().findElements(findStrategy.convert()); + var nativeElements = getWrappedDriver().findElements(findStrategy.convert()); List componentList = new ArrayList<>(); for (int i = 0; i < nativeElements.size(); i++) { var component = InstanceFactory.create(componentClass);