Skip to content
Merged
8 changes: 4 additions & 4 deletions .github/workflows/e2eTests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ jobs:
run: docker ps
- name: Run tests
continue-on-error: true
run: mvn -e test "-DdefaultElementIdentificationTimeout=5" "-DsetParallelMode=DYNAMIC" "-DsetParallel=METHODS" "-DretryMaximumNumberOfAttempts=1" "-DexecutionAddress=localhost:4444" "-DtargetOperatingSystem=LINUX" "-DtargetBrowserName=firefox" "-DheadlessExecution=true" "-DgenerateAllureReportArchive=true" "-Dtest=${GLOBAL_TESTING_SCOPE}"
run: mvn -e test "-DdefaultElementIdentificationTimeout=5" "-DsetParallelMode=DYNAMIC" "-DsetParallel=METHODS" "-DretryMaximumNumberOfAttempts=1" "-DexecutionAddress=http://localhost:4444" "-DtargetOperatingSystem=LINUX" "-DtargetBrowserName=firefox" "-DheadlessExecution=true" "-DgenerateAllureReportArchive=true" "-Dtest=${GLOBAL_TESTING_SCOPE}"
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v5
with:
Expand Down Expand Up @@ -162,7 +162,7 @@ jobs:
run: docker ps
- name: Run tests
continue-on-error: true
run: mvn -e test "-DdefaultElementIdentificationTimeout=5" "-DsetParallelMode=DYNAMIC" "-DsetParallel=METHODS" "-DretryMaximumNumberOfAttempts=1" "-DexecutionAddress=localhost:4444" "-DtargetOperatingSystem=LINUX" "-DtargetBrowserName=chrome" "-DheadlessExecution=true" "-DgenerateAllureReportArchive=true" "-Dtest=${GLOBAL_TESTING_SCOPE}"
run: mvn -e test "-DdefaultElementIdentificationTimeout=5" "-DsetParallelMode=DYNAMIC" "-DsetParallel=METHODS" "-DretryMaximumNumberOfAttempts=1" "-DexecutionAddress=http://localhost:4444" "-DtargetOperatingSystem=LINUX" "-DtargetBrowserName=chrome" "-DheadlessExecution=true" "-DgenerateAllureReportArchive=true" "-Dtest=${GLOBAL_TESTING_SCOPE}"
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v5
with:
Expand Down Expand Up @@ -202,7 +202,7 @@ jobs:
run: docker ps
- name: Run tests
continue-on-error: true
run: mvn -e test "-DdefaultElementIdentificationTimeout=5" "-DsetParallelMode=DYNAMIC" "-DsetParallel=METHODS" "-DretryMaximumNumberOfAttempts=1" "-DexecutionAddress=localhost:4444" "-DtargetOperatingSystem=LINUX" "-DtargetBrowserName=MicrosoftEdge" "-DheadlessExecution=true" "-DgenerateAllureReportArchive=true" "-Dtest=${GLOBAL_TESTING_SCOPE}"
run: mvn -e test "-DdefaultElementIdentificationTimeout=5" "-DsetParallelMode=DYNAMIC" "-DsetParallel=METHODS" "-DretryMaximumNumberOfAttempts=1" "-DexecutionAddress=http://localhost:4444" "-DtargetOperatingSystem=LINUX" "-DtargetBrowserName=MicrosoftEdge" "-DheadlessExecution=true" "-DgenerateAllureReportArchive=true" "-Dtest=${GLOBAL_TESTING_SCOPE}"
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v5
with:
Expand Down Expand Up @@ -393,7 +393,7 @@ jobs:
- name: Run tests on Linux/MacOS
if: runner.os != 'Windows'
continue-on-error: true
run: mvn -e test "-DdefaultElementIdentificationTimeout=5" "-DsetParallelMode=DYNAMIC" "-DsetParallel=METHODS" "-DretryMaximumNumberOfAttempts=1" "-DexecutionAddress=localhost:4444" "-DtargetOperatingSystem=LINUX" "-DtargetBrowserName=chrome" "-DmaximumPerformanceMode=2" "-DgenerateAllureReportArchive=true" "-Dtest=%regex[.*CucumberTests.*]"
run: mvn -e test "-DdefaultElementIdentificationTimeout=5" "-DsetParallelMode=DYNAMIC" "-DsetParallel=METHODS" "-DretryMaximumNumberOfAttempts=1" "-DexecutionAddress=http://localhost:4444" "-DtargetOperatingSystem=LINUX" "-DtargetBrowserName=chrome" "-DmaximumPerformanceMode=2" "-DgenerateAllureReportArchive=true" "-Dtest=%regex[.*CucumberTests.*]"
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v5
with:
Expand Down
29 changes: 5 additions & 24 deletions src/main/java/com/shaft/driver/SHAFT.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@
import com.shaft.tools.io.*;
import com.shaft.tools.io.internal.ReportManagerHelper;
import com.shaft.validation.internal.RestValidationsBuilder;
import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.ios.IOSDriver;
import io.appium.java_client.AppiumDriver;
import io.restassured.response.Response;
import org.openqa.selenium.MutableCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.events.EventFiringDecorator;

import java.io.InputStream;
Expand Down Expand Up @@ -87,37 +87,18 @@ public WizardHelpers.WebDriverVerifications verifyThat() {
*
* @return the current Selenium WebDriver instance for custom manipulation
*/
@SuppressWarnings("CommentedOutCode")
public org.openqa.selenium.WebDriver getDriver() {
/*
* Decorator is not working for appium drivers as per the following issues/articles
* https://github.com/appium/java-client/issues/1694
* https://github.com/appium/java-client/blob/master/docs/The-event_firing.md#createproxy-api-since-java-client-830
* https://github.com/SeleniumHQ/selenium/blob/316f9738a8e2079265a0691954ca8847e68c598d/java/test/org/openqa/selenium/support/events/EventFiringDecoratorTest.java#L422
*/
if (helper.getDriver() instanceof AndroidDriver androidDriver) {
// AndroidDriver decoratedDriver = createProxy(
// AndroidDriver.class,
// new Object[] {androidDriver},
// new Class[] {AndroidDriver.class},
// webDriverListener
// );
// return decoratedDriver;
// return new EventFiringDecorator<>(AndroidDriver.class, listener).decorate(androidDriver);
if (helper.getDriver() instanceof AppiumDriver | helper.getDriver() instanceof RemoteWebDriver) {
// remote execution
return helper.getDriver();
} else if (helper.getDriver() instanceof IOSDriver iosDriver) {
// IOSDriver decoratedDriver = createProxy(
// IOSDriver.class,
// new Object[] {iosDriver},
// new Class[] {IOSDriver.class},
// webDriverListener
// );
// return decoratedDriver;
// return new EventFiringDecorator<>(IOSDriver.class, listener).decorate(iosDriver);
return helper.getDriver();
// } else if (driverThreadLocal.get() instanceof RemoteWebDriver remoteWebDriver) {
// driverThreadLocal.set(new EventFiringDecorator<>(RemoteWebDriver.class, new WebDriverListener()).decorate(remoteWebDriver));
} else {
// local execution
if (!SHAFT.Properties.flags.enableTrueNativeMode()) {
return new EventFiringDecorator<>(org.openqa.selenium.WebDriver.class, new WebDriverListener()).decorate(helper.getDriver());
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.Level;
import org.openqa.selenium.*;
import org.openqa.selenium.bidi.BiDiProvider;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.Command;
import org.openqa.selenium.devtools.DevTools;
Expand All @@ -32,6 +33,7 @@
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.remote.*;
import org.openqa.selenium.remote.http.ConnectionFailedException;
import org.openqa.selenium.safari.SafariDriver;
import org.testng.Reporter;

Expand Down Expand Up @@ -165,7 +167,7 @@ private static int attemptRemoteServerPing() {
return statusCode;
}

@SneakyThrows({MalformedURLException.class, InterruptedException.class})
@SneakyThrows({InterruptedException.class, MalformedURLException.class})
private static WebDriver attemptRemoteServerConnection(Capabilities capabilities) {
WebDriver driver = null;
boolean isRemoteConnectionEstablished = false;
Expand All @@ -175,7 +177,8 @@ private static WebDriver attemptRemoteServerConnection(Capabilities capabilities
try {
driver = connectToRemoteServer(capabilities, false);
isRemoteConnectionEstablished = true;
} catch (SessionNotCreatedException | URISyntaxException sessionNotCreatedException1) {
} catch (SessionNotCreatedException | URISyntaxException |
ConnectionFailedException sessionNotCreatedException1) {
exception = sessionNotCreatedException1;
String message = sessionNotCreatedException1.getMessage();
if (message !=null &&
Expand All @@ -188,7 +191,7 @@ private static WebDriver attemptRemoteServerConnection(Capabilities capabilities
driver = connectToRemoteServer(capabilities, true);
isRemoteConnectionEstablished = true;
} catch (SessionNotCreatedException |
URISyntaxException sessionNotCreatedException2) {
URISyntaxException | ConnectionFailedException sessionNotCreatedException2) {
// do nothing
exception = sessionNotCreatedException2;
ReportManagerHelper.logDiscrete(sessionNotCreatedException1, Level.DEBUG);
Expand All @@ -208,7 +211,7 @@ private static WebDriver attemptRemoteServerConnection(Capabilities capabilities
return driver;
}

private static WebDriver connectToRemoteServer(Capabilities capabilities, boolean isLegacy) throws MalformedURLException, URISyntaxException {
private static WebDriver connectToRemoteServer(Capabilities capabilities, boolean isLegacy) throws URISyntaxException, MalformedURLException {
var targetHubUrl = TARGET_HUB_URL;
if (isLegacy) {
if (StringUtils.isNumeric(TARGET_HUB_URL.substring(TARGET_HUB_URL.length() - 1))) {
Expand All @@ -223,32 +226,36 @@ private static WebDriver connectToRemoteServer(Capabilities capabilities, boolea
var targetPlatform = Properties.platform.targetPlatform();
var targetMobileHubUrl = targetHubUrl.replace("@", "@mobile-").replace("http", "https");

if (targetPlatform.equalsIgnoreCase(Platform.ANDROID.toString())) {
if (SHAFT.Properties.platform.executionAddress().contains("lambdatest") && !isMobileWebExecution()) {
return new AndroidDriver(new URI(targetMobileHubUrl).toURL(), capabilities);
} else {
if (SHAFT.Properties.platform.executionAddress().contains("lambdatest")) {
return new AndroidDriver(new URI(targetLambdaTestHubURL).toURL(), capabilities);
} else {
return new AndroidDriver(new URI(targetHubUrl).toURL(), capabilities);
}
}
} else if (targetPlatform.equalsIgnoreCase(Platform.IOS.toString())) {
if (SHAFT.Properties.platform.executionAddress().contains("lambdatest") && !isMobileWebExecution()) {
return new IOSDriver(new URI(targetMobileHubUrl).toURL(), capabilities);
} else {
if (SHAFT.Properties.platform.executionAddress().contains("lambdatest")) {
return new IOSDriver(new URI(targetLambdaTestHubURL).toURL(), capabilities);
} else {
return new IOSDriver(new URI(targetHubUrl).toURL(), capabilities);
}
}
} else {
if (SHAFT.Properties.platform.executionAddress().contains("lambdatest")) {
return new RemoteWebDriver(new URI(targetLambdaTestHubURL).toURL(), capabilities, false);
} else {
return new RemoteWebDriver(new URI(targetHubUrl).toURL(), capabilities, false);
var isAndroidExecution = targetPlatform.equalsIgnoreCase(Platform.ANDROID.toString());
var isIosExecution = targetPlatform.equalsIgnoreCase(Platform.IOS.toString());
var isLambdaTestExecution = SHAFT.Properties.platform.executionAddress().contains("lambdatest");

var targetExecutionUrl = "";

if (isLambdaTestExecution && !isMobileWebExecution()) targetExecutionUrl = targetMobileHubUrl;
else if (isLambdaTestExecution) targetExecutionUrl = targetLambdaTestHubURL;
else targetExecutionUrl = targetHubUrl;

ReportManagerHelper.logDiscrete("Target Execution URI after processing: `" + targetExecutionUrl + "`, and capabilities after processing: `" + capabilities.toString() + "`.", Level.DEBUG);
try {
//builder code block, has issues in many cases, test it locally via grid before using it
// if (isAndroidExecution) return AndroidDriver.builder().address(targetExecutionUrl).oneOf(capabilities).build();
// else if (isIosExecution) return IOSDriver.builder().address(targetExecutionUrl).oneOf(capabilities).build();
// else return RemoteWebDriver.builder().address(targetExecutionUrl).oneOf(capabilities).build();
// legacy constructor-based code block
if (isAndroidExecution) return new AndroidDriver(new URI(targetExecutionUrl).toURL(), capabilities);
else if (isIosExecution) return new IOSDriver(new URI(targetExecutionUrl).toURL(), capabilities);
else {
var driver = new RemoteWebDriver(new URI(targetExecutionUrl).toURL(), capabilities);
if (!SHAFT.Properties.platform.enableBiDi())
return driver;
var augmenter = new Augmenter();
augmenter.addDriverAugmentation(new BiDiProvider());
return augmenter.augment(driver);
}
} catch (Throwable throwable) {
ReportManagerHelper.logDiscrete(throwable, Level.DEBUG);
throw throwable;
}
}

Expand Down Expand Up @@ -517,19 +524,22 @@ private void setRemoteDriverInstance(Capabilities capabilities) {
ReportManager.logDiscrete("Attempting to instantiate remote driver instance for up to " + TimeUnit.SECONDS.toMinutes(remoteServerInstanceCreationTimeout) + "min.");
try (ProgressBarLogger pblogger = new ProgressBarLogger("Instantiating...", (int) remoteServerInstanceCreationTimeout)) {
setDriver(attemptRemoteServerConnection(capabilities));
((RemoteWebDriver) driver).setFileDetector(new LocalFileDetector());
if (!isNotMobileExecution() && SHAFT.Properties.platform.targetPlatform().equalsIgnoreCase("Android")) {
if (driver instanceof RemoteWebDriver remoteWebDriver)
remoteWebDriver.setFileDetector(new LocalFileDetector());
if (!isNotMobileExecution()
&& SHAFT.Properties.platform.targetPlatform().equalsIgnoreCase("Android")
&& (driver instanceof AppiumDriver appiumDriver)) {
// https://github.com/appium/appium-uiautomator2-driver#settings-api
((AppiumDriver) driver).setSetting(Setting.WAIT_FOR_IDLE_TIMEOUT, 5000);
((AppiumDriver) driver).setSetting(Setting.ALLOW_INVISIBLE_ELEMENTS, true);
((AppiumDriver) driver).setSetting(Setting.IGNORE_UNIMPORTANT_VIEWS, false);
((AppiumDriver) driver).setSetting("enableMultiWindows", true);
appiumDriver.setSetting(Setting.WAIT_FOR_IDLE_TIMEOUT, 5000);
appiumDriver.setSetting(Setting.ALLOW_INVISIBLE_ELEMENTS, true);
appiumDriver.setSetting(Setting.IGNORE_UNIMPORTANT_VIEWS, false);
appiumDriver.setSetting("enableMultiWindows", true);
// elementResponseAttributes, shouldUseCompactResponses
((AppiumDriver) driver).setSetting(Setting.MJPEG_SCALING_FACTOR, 25);
((AppiumDriver) driver).setSetting(Setting.MJPEG_SERVER_SCREENSHOT_QUALITY, 100);
((AppiumDriver) driver).setSetting("mjpegBilinearFiltering", true);
// ((AppiumDriver) driver).setSetting("limitXPathContextScope", false);
// ((AppiumDriver) driver).setSetting("disableIdLocatorAutocompletion", true);
appiumDriver.setSetting(Setting.MJPEG_SCALING_FACTOR, 25);
appiumDriver.setSetting(Setting.MJPEG_SERVER_SCREENSHOT_QUALITY, 100);
appiumDriver.setSetting("mjpegBilinearFiltering", true);
// appiumDriver.setSetting("limitXPathContextScope", false);
// appiumDriver.setSetting("disableIdLocatorAutocompletion", true);
// https://github.com/appium/appium-uiautomator2-driver#mobile-deeplink
// http://code2test.com/appium-tutorial/how-to-use-uiselector-in-appium/
// https://github.com/appium/appium-uiautomator2-driver
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,6 @@
import org.openqa.selenium.safari.SafariOptions;

import java.io.File;
import java.io.IOException;
import java.net.ServerSocket;
import java.time.Duration;
import java.util.Arrays;
import java.util.HashMap;
Expand Down Expand Up @@ -399,17 +397,8 @@ private ChromiumOptions<?> setupChromiumOptions(ChromiumOptions<?> options, Muta
// Add if condtion to start the new session if flag=true on specific port
if (SHAFT.Properties.performance.isEnabled()) {
options.addArguments("--remote-debugging-port=" + SHAFT.Properties.performance.port());
} else {
// last edited to fix https://github.com/ShaftHQ/SHAFT_ENGINE/issues/1780
// options.addArguments("--remote-debugging-pipe"); //this is supposed to be needed to support CDP
// a seeming fix is to remove the above line, however I believe that setting a dynamic free port is better
// as a fallback precaution I will leave the old code in case SHAFT failed to find a free available port
try (ServerSocket serverSocket = new ServerSocket(0)) {
options.addArguments("--remote-debugging-port=" + serverSocket.getLocalPort());
} catch (IOException e) {
options.addArguments("--remote-debugging-pipe");
}
}

// browser window size and position
if (SHAFT.Properties.flags.autoMaximizeBrowserWindow() && !Platform.ANDROID.toString().equalsIgnoreCase(SHAFT.Properties.platform.targetPlatform()) && !Platform.IOS.toString().equalsIgnoreCase(SHAFT.Properties.platform.targetPlatform()) && !Platform.MAC.toString().equalsIgnoreCase(SHAFT.Properties.platform.targetPlatform())) {
options.addArguments("--start-maximized");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,15 @@ public static void fail(Class<?> failedFileManager, String message, Throwable th
attachments.add(actualValueAttachment);
ReportManagerHelper.log(message + rootCause, attachments);
}
if (message.toLowerCase().contains("assert"))
throw new AssertionError(message + rootCause, throwable);
throw new RuntimeException(message + rootCause, throwable);
}

public static void fail(String message) {
ReportManager.log(message);
if (message.toLowerCase().contains("assert"))
throw new AssertionError(message);
throw new RuntimeException(message);
}

Expand Down
Loading
Loading