How to use castDriver method of com.qaprosoft.carina.core.foundation.webdriver.IDriverPool class

Best Carina code snippet using com.qaprosoft.carina.core.foundation.webdriver.IDriverPool.castDriver

Source:IMobileUtils.java Github

copy

Full Screen

...115 default public boolean longPress(ExtendedWebElement element) {116 UTILS_LOGGER.info("longPress on" + element.getName());117 // TODO: SZ migrate to FluentWaits118 try {119 WebDriver driver = castDriver();120 @SuppressWarnings("rawtypes")121 TouchAction<?> action = new TouchAction((MobileDriver<?>) driver);122 LongPressOptions options = LongPressOptions.longPressOptions().withElement(ElementOption.element(element.getElement()));123 action.longPress(options).release().perform();124 return true;125 } catch (Exception e) {126 UTILS_LOGGER.info("Error occurs during longPress: " + e, e);127 }128 return false;129 }130 /**131 * Tap with TouchAction by coordinates with custom duration132 *133 * @param startx int134 * @param starty int135 * @param duration int136 */137 default public void tap(int startx, int starty, int duration) {138 // TODO: add Screenshot.capture()139 try {140 @SuppressWarnings("rawtypes")141 TouchAction<?> touchAction = new TouchAction((MobileDriver<?>) castDriver());142 PointOption<?> startPoint = PointOption.point(startx, starty);143 WaitOptions waitOptions = WaitOptions.waitOptions(Duration.ofMillis(duration));144 if (duration == 0) {145 // do not perform waiter as using 6.0.0. appium java client we do longpress instead of simple tap even with 0 wait duration146 touchAction.press(startPoint).release().perform();147 } else {148 touchAction.press(startPoint).waitAction(waitOptions).release().perform();149 }150 Messager.TAP_EXECUTED.info(String.valueOf(startx), String.valueOf(starty));151 } catch (Exception e) {152 Messager.TAP_NOT_EXECUTED.error(String.valueOf(startx), String.valueOf(starty));153 throw e;154 }155 }156 /**157 * swipe till element using TouchActions158 *159 * @param element ExtendedWebElement160 * @return boolean161 */162 default public boolean swipe(final ExtendedWebElement element) {163 return swipe(element, null, Direction.UP, DEFAULT_MAX_SWIPE_COUNT, DEFAULT_TOUCH_ACTION_DURATION);164 }165 /**166 * swipe till element using TouchActions167 *168 * @param element ExtendedWebElement169 * @param count int170 * @return boolean171 */172 default public boolean swipe(final ExtendedWebElement element, int count) {173 return swipe(element, null, Direction.UP, count, DEFAULT_TOUCH_ACTION_DURATION);174 }175 /**176 * swipe till element using TouchActions177 *178 * @param element ExtendedWebElement179 * @param direction Direction180 * @return boolean181 */182 default public boolean swipe(final ExtendedWebElement element, Direction direction) {183 return swipe(element, null, direction, DEFAULT_MAX_SWIPE_COUNT, DEFAULT_TOUCH_ACTION_DURATION);184 }185 /**186 * swipe till element using TouchActions187 *188 * @param element ExtendedWebElement189 * @param count int190 * @param duration int191 * @return boolean192 */193 default public boolean swipe(final ExtendedWebElement element, int count, int duration) {194 return swipe(element, null, Direction.UP, count, duration);195 }196 /**197 * swipe till element using TouchActions198 *199 * @param element ExtendedWebElement200 * @param direction Direction201 * @param count int202 * @param duration int203 * @return boolean204 */205 default public boolean swipe(final ExtendedWebElement element, Direction direction, int count, int duration) {206 return swipe(element, null, direction, count, duration);207 }208 /**209 * Swipe inside container in default direction - Direction.UP210 * Number of attempts is limited by count argument211 * <p>212 *213 * @param element214 * ExtendedWebElement215 * @param container216 * ExtendedWebElement217 * @param count218 * int219 * @return boolean220 */221 default public boolean swipe(ExtendedWebElement element, ExtendedWebElement container, int count) {222 return swipe(element, container, Direction.UP, count, DEFAULT_TOUCH_ACTION_DURATION);223 }224 /**225 * Swipe inside container in default direction - Direction.UP226 * Number of attempts is limited by 5227 * <p>228 *229 * @param element230 * ExtendedWebElement231 * @param container232 * ExtendedWebElement233 * @return boolean234 */235 default public boolean swipe(ExtendedWebElement element, ExtendedWebElement container) {236 return swipe(element, container, Direction.UP, DEFAULT_MAX_SWIPE_COUNT, DEFAULT_TOUCH_ACTION_DURATION);237 }238 /**239 * Swipe inside container in specified direction240 * Number of attempts is limited by 5241 * <p>242 *243 * @param element244 * ExtendedWebElement245 * @param container246 * ExtendedWebElement247 * @param direction248 * Direction249 * @return boolean250 */251 default public boolean swipe(ExtendedWebElement element, ExtendedWebElement container, Direction direction) {252 return swipe(element, container, direction, DEFAULT_MAX_SWIPE_COUNT, DEFAULT_TOUCH_ACTION_DURATION);253 }254 /**255 * Swipe inside container in specified direction with default pulling timeout in 1000ms256 * Number of attempts is limited by count argument257 * <p>258 *259 * @param element260 * ExtendedWebElement261 * @param container262 * ExtendedWebElement263 * @param direction264 * Direction265 * @param count266 * int267 * @return boolean268 */269 default public boolean swipe(ExtendedWebElement element, ExtendedWebElement container, Direction direction,270 int count) {271 return swipe(element, container, direction, count, DEFAULT_TOUCH_ACTION_DURATION);272 }273 /**274 * Swipe to element inside container in specified direction while element275 * will not be present on the screen. If element is on the screen already,276 * scrolling will not be performed.277 * <p>278 *279 * @param element280 * element to which it will be scrolled281 * @param container282 * element, inside which scrolling is expected. null to scroll283 * @param direction284 * direction of scrolling. HORIZONTAL and VERTICAL support swiping in both directions automatically285 * @param count286 * for how long to scroll, ms287 * @param duration288 * pulling timeout, ms289 * @return boolean290 */291 default public boolean swipe(ExtendedWebElement element, ExtendedWebElement container, Direction direction,292 int count, int duration) {293 boolean isVisible = element.isVisible(1);294 if (isVisible) {295 // no sense to continue;296 UTILS_LOGGER.info("element already present before swipe: " + element.getNameWithLocator().toString());297 return true;298 } else {299 UTILS_LOGGER.info("swiping to element: " + element.getNameWithLocator().toString());300 }301 Direction oppositeDirection = Direction.DOWN;302 boolean bothDirections = false;303 switch (direction) {304 case UP:305 oppositeDirection = Direction.DOWN;306 break;307 case DOWN:308 oppositeDirection = Direction.UP;309 break;310 case LEFT:311 oppositeDirection = Direction.RIGHT;312 break;313 case RIGHT:314 oppositeDirection = Direction.LEFT;315 break;316 case HORIZONTAL:317 direction = Direction.LEFT;318 oppositeDirection = Direction.RIGHT;319 bothDirections = true;320 break;321 case HORIZONTAL_RIGHT_FIRST:322 direction = Direction.RIGHT;323 oppositeDirection = Direction.LEFT;324 bothDirections = true;325 break;326 case VERTICAL:327 direction = Direction.UP;328 oppositeDirection = Direction.DOWN;329 bothDirections = true;330 break;331 case VERTICAL_DOWN_FIRST:332 direction = Direction.DOWN;333 oppositeDirection = Direction.UP;334 bothDirections = true;335 break;336 default:337 throw new RuntimeException("Unsupported direction for swipeInContainerTillElement: " + direction);338 }339 int currentCount = count;340 while (!isVisible && currentCount-- > 0) {341 UTILS_LOGGER.debug("Element not present! Swipe " + direction + " will be executed to element: " + element.getNameWithLocator().toString());342 swipeInContainer(container, direction, duration);343 UTILS_LOGGER.info("Swipe was executed. Attempts remain: " + currentCount);344 isVisible = element.isVisible(1);345 }346 currentCount = count;347 while (bothDirections && !isVisible && currentCount-- > 0) {348 UTILS_LOGGER.debug(349 "Element not present! Swipe " + oppositeDirection + " will be executed to element: " + element.getNameWithLocator().toString());350 swipeInContainer(container, oppositeDirection, duration);351 UTILS_LOGGER.info("Swipe was executed. Attempts remain: " + currentCount);352 isVisible = element.isVisible(1);353 }354 UTILS_LOGGER.info("Result: " + isVisible);355 return isVisible;356 }357 /**358 * Swipe by coordinates using TouchAction (platform independent)359 *360 * @param startx int361 * @param starty int362 * @param endx int363 * @param endy int364 * @param duration int Millis365 */366 @SuppressWarnings("rawtypes")367 default public void swipe(int startx, int starty, int endx, int endy, int duration) {368 UTILS_LOGGER.debug("Starting swipe...");369 WebDriver drv = castDriver();370 UTILS_LOGGER.debug("Getting driver dimension size...");371 Dimension scrSize = drv.manage().window().getSize();372 UTILS_LOGGER.debug("Finished driver dimension size...");373 // explicitly limit range of coordinates374 if (endx >= scrSize.width) {375 UTILS_LOGGER.warn("endx coordinate is bigger then device width! It will be limited!");376 endx = scrSize.width - 1;377 } else {378 endx = Math.max(1, endx);379 }380 if (endy >= scrSize.height) {381 UTILS_LOGGER.warn("endy coordinate is bigger then device height! It will be limited!");382 endy = scrSize.height - 1;383 } else {384 endy = Math.max(1, endy);385 }386 UTILS_LOGGER.debug("startx: " + startx + "; starty: " + starty + "; endx: " + endx + "; endy: " + endy387 + "; duration: " + duration);388 PointOption<?> startPoint = PointOption.point(startx, starty);389 PointOption<?> endPoint = PointOption.point(endx, endy);390 WaitOptions waitOptions = WaitOptions.waitOptions(Duration.ofMillis(duration));391 new TouchAction((MobileDriver<?>) drv).press(startPoint).waitAction(waitOptions).moveTo(endPoint).release()392 .perform();393 UTILS_LOGGER.debug("Finished swipe...");394 }395 /**396 * swipeInContainer397 *398 * @param container ExtendedWebElement399 * @param direction Direction400 * @param duration int401 * @return boolean402 */403 default public boolean swipeInContainer(ExtendedWebElement container, Direction direction, int duration) {404 return swipeInContainer(container, direction, DEFAULT_MIN_SWIPE_COUNT, duration);405 }406 /**407 * swipeInContainer408 *409 * @param container ExtendedWebElement410 * @param direction Direction411 * @param count int412 * @param duration int413 * @return boolean414 */415 default public boolean swipeInContainer(ExtendedWebElement container, Direction direction, int count, int duration) {416 int startx = 0;417 int starty = 0;418 int endx = 0;419 int endy = 0;420 Point elementLocation = null;421 Dimension elementDimensions = null;422 if (container == null) {423 // whole screen/driver is a container!424 WebDriver driver = castDriver();425 elementLocation = new Point(0, 0); // initial left corner for that case426 elementDimensions = driver.manage().window().getSize();427 } else {428 if (container.isElementNotPresent(5)) {429 Assert.fail("Cannot swipe! Impossible to find element " + container.getName());430 }431 elementLocation = container.getLocation();432 elementDimensions = container.getSize();433 }434 double minCoefficient = 0.3;435 double maxCoefficient = 0.6;436 // calculate default coefficient based on OS type437 String os = IDriverPool.getDefaultDevice().getOs();438 if (os.equalsIgnoreCase(SpecialKeywords.ANDROID)) {439 minCoefficient = 0.25;440 maxCoefficient = 0.5;441 } else if (os.equalsIgnoreCase(SpecialKeywords.IOS) || os.equalsIgnoreCase(SpecialKeywords.MAC) || os.equalsIgnoreCase(SpecialKeywords.TVOS)) {442 minCoefficient = 0.25;443 maxCoefficient = 0.8;444 }445 switch (direction) {446 case LEFT:447 starty = endy = elementLocation.getY() + Math.round(elementDimensions.getHeight() / 2f);448 startx = (int) (elementLocation.getX() + Math.round(maxCoefficient * elementDimensions.getWidth()));449 endx = (int) (elementLocation.getX() + Math.round(minCoefficient * elementDimensions.getWidth()));450 break;451 case RIGHT:452 starty = endy = elementLocation.getY() + Math.round(elementDimensions.getHeight() / 2f);453 startx = (int) (elementLocation.getX() + Math.round(minCoefficient * elementDimensions.getWidth()));454 endx = (int) (elementLocation.getX() + Math.round(maxCoefficient * elementDimensions.getWidth()));455 break;456 case UP:457 startx = endx = elementLocation.getX() + Math.round(elementDimensions.getWidth() / 2f);458 starty = (int) (elementLocation.getY() + Math.round(maxCoefficient * elementDimensions.getHeight()));459 endy = (int) (elementLocation.getY() + Math.round(minCoefficient * elementDimensions.getHeight()));460 break;461 case DOWN:462 startx = endx = elementLocation.getX() + Math.round(elementDimensions.getWidth() / 2f);463 starty = (int) (elementLocation.getY() + Math.round(minCoefficient * elementDimensions.getHeight()));464 endy = (int) (elementLocation.getY() + Math.round(maxCoefficient * elementDimensions.getHeight()));465 break;466 default:467 throw new RuntimeException("Unsupported direction: " + direction);468 }469 UTILS_LOGGER.debug(String.format("Swipe from (X = %d; Y = %d) to (X = %d; Y = %d)", startx, starty, endx, endy));470 try {471 for (int i = 0; i < count; ++i) {472 swipe(startx, starty, endx, endy, duration);473 }474 return true;475 } catch (Exception e) {476 UTILS_LOGGER.error(String.format("Error during Swipe from (X = %d; Y = %d) to (X = %d; Y = %d): %s", startx, starty, endx, endy, e));477 }478 return false;479 }480 /**481 * Swipe up several times482 *483 * @param times int484 * @param duration int485 */486 default public void swipeUp(final int times, final int duration) {487 for (int i = 0; i < times; i++) {488 swipeUp(duration);489 }490 }491 /**492 * Swipe up493 *494 * @param duration int495 */496 default public void swipeUp(final int duration) {497 UTILS_LOGGER.info("Swipe up will be executed.");498 swipeInContainer(null, Direction.UP, duration);499 }500 /**501 * Swipe down several times502 *503 * @param times int504 * @param duration int505 */506 default public void swipeDown(final int times, final int duration) {507 for (int i = 0; i < times; i++) {508 swipeDown(duration);509 }510 }511 /**512 * Swipe down513 *514 * @param duration int515 */516 default public void swipeDown(final int duration) {517 UTILS_LOGGER.info("Swipe down will be executed.");518 swipeInContainer(null, Direction.DOWN, duration);519 }520 /**521 * Swipe left several times522 *523 * @param times int524 * @param duration int525 */526 default public void swipeLeft(final int times, final int duration) {527 for (int i = 0; i < times; i++) {528 swipeLeft(duration);529 }530 }531 /**532 * Swipe left533 *534 * @param duration int535 */536 default public void swipeLeft(final int duration) {537 UTILS_LOGGER.info("Swipe left will be executed.");538 swipeLeft(null, duration);539 }540 /**541 * Swipe left in container542 *543 * @param container544 * ExtendedWebElement545 * @param duration546 * int547 */548 default public void swipeLeft(ExtendedWebElement container, final int duration) {549 UTILS_LOGGER.info("Swipe left will be executed.");550 swipeInContainer(container, Direction.LEFT, duration);551 }552 /**553 * Swipe right several times554 *555 * @param times int556 * @param duration int557 */558 default public void swipeRight(final int times, final int duration) {559 for (int i = 0; i < times; i++) {560 swipeRight(duration);561 }562 }563 /**564 * Swipe right565 *566 * @param duration int567 */568 default public void swipeRight(final int duration) {569 UTILS_LOGGER.info("Swipe right will be executed.");570 swipeRight(null, duration);571 }572 /**573 * Swipe right in container574 *575 * @param container576 * ExtendedWebElement577 * @param duration578 * int579 */580 default public void swipeRight(ExtendedWebElement container, final int duration) {581 UTILS_LOGGER.info("Swipe right will be executed.");582 swipeInContainer(container, Direction.RIGHT, duration);583 }584 /**585 * Set Android Device Default TimeZone And Language based on config or to GMT and En586 * Without restoring actual focused apk.587 */588 default public void setDeviceDefaultTimeZoneAndLanguage() {589 setDeviceDefaultTimeZoneAndLanguage(false);590 }591 /**592 * set Android Device Default TimeZone And Language based on config or to GMT and En593 *594 * @param returnAppFocus - if true store actual Focused apk and activity, than restore after setting Timezone and Language.595 */596 default public void setDeviceDefaultTimeZoneAndLanguage(boolean returnAppFocus) {597 try {598 String baseApp = "";599 String os = IDriverPool.getDefaultDevice().getOs();600 if (os.equalsIgnoreCase(SpecialKeywords.ANDROID)) {601 AndroidService androidService = AndroidService.getInstance();602 if (returnAppFocus) {603 baseApp = androidService.getCurrentFocusedApkDetails();604 }605 String deviceTimezone = Configuration.get(Parameter.DEFAULT_DEVICE_TIMEZONE);606 String deviceTimeFormat = Configuration.get(Parameter.DEFAULT_DEVICE_TIME_FORMAT);607 String deviceLanguage = Configuration.get(Parameter.DEFAULT_DEVICE_LANGUAGE);608 DeviceTimeZone.TimeFormat timeFormat = DeviceTimeZone.TimeFormat.parse(deviceTimeFormat);609 DeviceTimeZone.TimeZoneFormat timeZone = DeviceTimeZone.TimeZoneFormat.parse(deviceTimezone);610 UTILS_LOGGER.info("Set device timezone to " + timeZone.toString());611 UTILS_LOGGER.info("Set device time format to " + timeFormat.toString());612 UTILS_LOGGER.info("Set device language to " + deviceLanguage);613 boolean timeZoneChanged = androidService.setDeviceTimeZone(timeZone.getTimeZone(), timeZone.getSettingsTZ(), timeFormat);614 boolean languageChanged = androidService.setDeviceLanguage(deviceLanguage);615 UTILS_LOGGER.info(String.format("Device TimeZone was changed to timeZone '%s' : %s. Device Language was changed to language '%s': %s",616 deviceTimezone,617 timeZoneChanged, deviceLanguage, languageChanged));618 if (returnAppFocus) {619 androidService.openApp(baseApp);620 }621 } else {622 UTILS_LOGGER.info(String.format("Current OS is %s. But we can set default TimeZone and Language only for Android.", os));623 }624 } catch (Exception e) {625 UTILS_LOGGER.error("Error while setting to device default timezone and language!", e);626 }627 }628 /**629 * Hide keyboard if needed630 */631 default public void hideKeyboard() {632 try {633 ((MobileDriver<?>) castDriver()).hideKeyboard();634 } catch (Exception e) {635 if (!e.getMessage().contains("Soft keyboard not present, cannot hide keyboard")) {636 UTILS_LOGGER.error("Exception appears during hideKeyboard: " + e);637 }638 }639 }640 /**641 * Check if keyboard is showing642 * return false if driver is not ios or android driver643 *644 * @return boolean645 */646 default public boolean isKeyboardShown() {647 MobileDriver<?> driver = (MobileDriver<?>) castDriver();648 if (driver instanceof IOSDriver) {649 return ((IOSDriver<?>) castDriver()).isKeyboardShown();650 }651 else if (driver instanceof AndroidDriver) {652 return ((AndroidDriver<?>) castDriver()).isKeyboardShown();653 }654 return false;655 }656 default public void zoom(Zoom type) {657 UTILS_LOGGER.info("Zoom will be performed :" + type);658 MobileDriver<?> driver = (MobileDriver<?>) castDriver();659 Dimension scrSize = driver.manage().window().getSize();660 int height = scrSize.getHeight();661 int width = scrSize.getWidth();662 UTILS_LOGGER.debug("Screen height : " + height);663 UTILS_LOGGER.debug("Screen width : " + width);664 Point point1 = new Point(width / 2, height / 2 - 30);665 Point point2 = new Point(width / 2, height / 10 * 3);666 Point point3 = new Point(width / 2, height / 2 + 30);667 Point point4 = new Point(width / 2, (7 * height) / 10);668 switch (type) {669 case OUT:670 zoom(point1.getX(), point1.getY(), point2.getX(), point2.getY(), point3.getX(), point3.getY(), point4.getX(), point4.getY(),671 DEFAULT_TOUCH_ACTION_DURATION);672 break;673 case IN:674 zoom(point2.getX(), point2.getY(), point1.getX(), point1.getY(), point4.getX(), point4.getY(), point3.getX(), point3.getY(),675 DEFAULT_TOUCH_ACTION_DURATION);676 break;677 }678 }679 default public void zoom(int startx1, int starty1, int endx1, int endy1, int startx2, int starty2, int endx2, int endy2, int duration) {680 UTILS_LOGGER.debug(String.format(681 "Zoom action will be performed with parameters : startX1 : %s ; startY1: %s ; endX1: %s ; endY1: %s; startX2 : %s ; startY2: %s ; endX2: %s ; endY2: %s",682 startx1, starty1, endx1, endy1, startx2, starty2, endx2, endy2));683 MobileDriver<?> driver = (MobileDriver<?>) castDriver();684 try {685 MultiTouchAction multiTouch = new MultiTouchAction(driver);686 @SuppressWarnings("rawtypes")687 TouchAction<?> tAction0 = new TouchAction(driver);688 @SuppressWarnings("rawtypes")689 TouchAction<?> tAction1 = new TouchAction(driver);690 PointOption<?> startPoint1 = PointOption.point(startx1, starty1);691 PointOption<?> endPoint1 = PointOption.point(endx1, endy1);692 PointOption<?> startPoint2 = PointOption.point(startx2, starty2);693 PointOption<?> endPoint2 = PointOption.point(endx2, endy2);694 WaitOptions waitOptions = WaitOptions.waitOptions(Duration.ofMillis(duration));695 tAction0.press(startPoint1).waitAction(waitOptions).moveTo(endPoint1).release();696 tAction1.press(startPoint2).waitAction(waitOptions).moveTo(endPoint2).release();697 multiTouch.add(tAction0).add(tAction1);698 multiTouch.perform();699 UTILS_LOGGER.info("Zoom has been performed");700 } catch (Exception e) {701 UTILS_LOGGER.error("Error during zooming", e);702 }703 }704 /**705 * Check if started driver/application is running in foreground706 *707 * @return boolean708 */709 default public boolean isAppRunning() {710 String bundleId = "";711 String os = getDevice().getOs();712 // get bundleId or appId of the application started by driver713 if (os.equalsIgnoreCase(SpecialKeywords.ANDROID)) {714 bundleId = ((AppiumDriver<?>) castDriver()).getSessionDetail(SpecialKeywords.APP_PACKAGE).toString();715 } else if (os.equalsIgnoreCase(SpecialKeywords.IOS) || os.equalsIgnoreCase(SpecialKeywords.MAC) || os.equalsIgnoreCase(SpecialKeywords.TVOS)) {716 bundleId = ((AppiumDriver<?>) castDriver()).getSessionDetail(SpecialKeywords.BUNDLE_ID).toString();717 }718 return isAppRunning(bundleId);719 }720 /**721 * Check running in foreground application by bundleId or appId722 *723 * @param bundleId the bundle identifier for iOS (or appPackage for Android) of the app to query the state of.724 * @return boolean725 */726 default public boolean isAppRunning(String bundleId) {727 ApplicationState actualApplicationState = ((MobileDriver<?>) castDriver()).queryAppState(bundleId);728 return ApplicationState.RUNNING_IN_FOREGROUND.equals(actualApplicationState);729 }730 /**731 * Terminate running driver/application732 */733 default public void terminateApp() {734 String bundleId = "";735 String os = getDevice().getOs();736 // get bundleId or appId of the application started by driver737 if (os.equalsIgnoreCase(SpecialKeywords.ANDROID)) {738 bundleId = ((AppiumDriver<?>) castDriver()).getSessionDetail(SpecialKeywords.APP_PACKAGE).toString();739 } else if (os.equalsIgnoreCase(SpecialKeywords.IOS) || os.equalsIgnoreCase(SpecialKeywords.MAC) || os.equalsIgnoreCase(SpecialKeywords.TVOS)) {740 bundleId = ((AppiumDriver<?>) castDriver()).getSessionDetail(SpecialKeywords.BUNDLE_ID).toString();741 }742 terminateApp(bundleId);743 }744 /**745 * Terminate running application by bundleId or appId746 *747 * @param bundleId the bundle identifier for iOS (or appPackage for Android) of the app to terminate.748 */749 default public void terminateApp(String bundleId) {750 ((MobileDriver<?>) castDriver()).terminateApp(bundleId);751 }752 753 /**754 * The application that has its package name set to current driver's755 * capabilities will be closed to background IN CASE IT IS CURRENTLY IN756 * FOREGROUND. Will be in recent app's list;757 */758 default public void closeApp() {759 UTILS_LOGGER.info("Application will be closed to background");760 ((MobileDriver<?>) castDriver()).closeApp();761 }762 /**763 * Cast Carina driver to WebDriver removing all extra listeners (try to avoid direct operations via WebDriver as it doesn't support logging etc)764 *765 * @return WebDriver766 */767 default public WebDriver castDriver() {768 WebDriver drv = getDriver();769 if (drv instanceof EventFiringWebDriver) {770 drv = ((EventFiringWebDriver) drv).getWrappedDriver();771 }772 return drv;773 }774 // TODO Update this method using findByImage strategy775 /**776 * Pressing bottom right button on the keyboard by coordinates: "search", "ok",777 * "next", etc. - various keys appear at this position. Tested at Nexus 6P778 * Android 8.0.0 standard keyboard. Coefficients of coordinates for other779 * devices and custom keyboards could be different.780 */781 @SuppressWarnings("rawtypes")782 default public void pressBottomRightKey() {783 WebDriver driver = castDriver();784 Dimension size = helper.performIgnoreException(() -> driver.manage().window().getSize());785 int height = size.getHeight();786 int width = size.getWidth();787 PointOption<?> option = PointOption.point((int) (width * 0.915), (int) (height * 0.945));788 new TouchAction((MobileDriver<?>) castDriver()).tap(option).perform();789 }790 default public boolean isChecked(final ExtendedWebElement element) {791 // TODO: SZ migrate to FluentWaits792 return element.isElementPresent(5)793 && (element.getElement().isSelected() || element.getAttribute("checked").equals("true"));794 }795 /**796 * If the application you're interested about is installed - returns "true".797 * Otherwise, returns "false".798 *799 * @param packageName800 * - app's package or bundle id801 * 802 * @return boolean803 */804 default public boolean isApplicationInstalled(String packageName) {805 boolean installed = ((MobileDriver<?>) castDriver()).isAppInstalled(packageName);806 UTILS_LOGGER.info(String.format("Application by package name (%s) installed: ", packageName) + installed);807 return installed;808 }809 /**810 * Method to launch Android application by its package name.811 *812 * Application should be installed to device.813 *814 * Application might not be running in background, but will be launched anyway.815 *816 * @param packageName817 * - app's package or bundle id818 */819 default public void startApp(String packageName) {820 UTILS_LOGGER.info("Starting " + packageName);821 ((MobileDriver<?>) castDriver()).activateApp(packageName);822 }823 /**824 * Will install application if path to apk-file on working machine is set.825 *826 * @param apkPath String827 */828 default public void installApp(String apkPath) {829 UTILS_LOGGER.info("Will install application with apk-file from " + apkPath);830 ((MobileDriver<?>) castDriver()).installApp(apkPath);831 }832 /**833 * To remove installed application by provided package name834 *835 * @param packageName836 * - app's package or bundle id837 *838 * @return true if succeed839 */840 default public boolean removeApp(String packageName) {841 boolean removed = ((MobileDriver<?>) castDriver()).removeApp(packageName);842 UTILS_LOGGER.info(String.format("Application (%s) is successfuly removed: ", packageName) + removed);843 return removed;844 }845 /**846 * Method to reset test application.847 *848 * App's settings will be reset. User will be logged out. Application will be849 * closed to background.850 */851 default public void clearAppCache() {852 UTILS_LOGGER.info("Initiation application reset...");853 ((MobileDriver<?>) castDriver()).resetApp();854 }855}...

Full Screen

Full Screen

Source:IDriverPool.java Github

copy

Full Screen

...278 private void quitDriver(CarinaDriver carinaDriver, boolean keepProxyDuring) {279 try {280 carinaDriver.getDevice().disconnectRemote();281 282 // castDriver to disable DriverListener operations on quit283 WebDriver drv = castDriver(carinaDriver.getDriver());284 POOL_LOGGER.debug("start driver quit: " + carinaDriver.getName());285 286 Future<?> future = Executors.newSingleThreadExecutor().submit(new Callable<Void>() {287 public Void call() throws Exception {288 if (Configuration.getBoolean(Parameter.CHROME_CLOSURE)) {289 // workaround to not cleaned chrome profiles on hard drive290 POOL_LOGGER.debug("Starting drv.close()");291 drv.close();292 POOL_LOGGER.debug("Finished drv.close()");293 }294 POOL_LOGGER.debug("Starting drv.quit()");295 drv.quit();296 POOL_LOGGER.debug("Finished drv.quit()");297 return null;298 }299 });300 301 // default timeout for driver quit 1/2 of explicit302 long timeout = Configuration.getInt(Parameter.EXPLICIT_TIMEOUT) / 2;303 try {304 future.get(timeout, TimeUnit.SECONDS);305 } catch (InterruptedException e) {306 POOL_LOGGER.error("InterruptedException: Unable to quit driver!", e);307 Thread.currentThread().interrupt();308 } catch (ExecutionException e) {309 if (e.getMessage() != null && e.getMessage().contains("not found in active sessions")) {310 POOL_LOGGER.warn("Skip driver quit for already disconnected session!");311 } else {312 POOL_LOGGER.error("ExecutionException: Unable to quit driver!", e);313 }314 } catch (java.util.concurrent.TimeoutException e) {315 POOL_LOGGER.error("Unable to quit driver for " + timeout + "sec!", e);316 }317 } catch (WebDriverException e) {318 POOL_LOGGER.debug("Error message detected during driver quit!", e);319 // do nothing320 } catch (Exception e) {321 POOL_LOGGER.error("Error discovered during driver quit!", e);322 } finally {323 POOL_LOGGER.debug("finished driver quit: " + carinaDriver.getName());324 if (!keepProxyDuring) {325 ProxyPool.stopProxy();326 }327 }328 }329 330 private WebDriver castDriver(WebDriver drv) {331 if (drv instanceof EventFiringWebDriver) {332 drv = ((EventFiringWebDriver) drv).getWrappedDriver();333 }334 return drv; 335 } 336 337 /**338 * Create driver with custom capabilities339 * 340 * @param name341 * String driver name342 * @param capabilities343 * DesiredCapabilities344 * @param seleniumHost...

Full Screen

Full Screen

Source:DriverListener.java Github

copy

Full Screen

...156 // TODO: investigate if we run @AfterMethod etc system events after this crash157 if (thr.getMessage().contains("is not running, possibly crashed")) {158 throw new RuntimeException(thr);159 }160 // hopefully castDriver below resolve root cause of the recursive onException calls but keep below to ensure161 if (thr.getStackTrace() != null162 && (Arrays.toString(thr.getStackTrace())163 .contains("com.qaprosoft.carina.core.foundation.webdriver.listener.DriverListener.onException")164 || Arrays.toString(thr.getStackTrace()).contains("Unable to capture screenshot due to the WebDriverException"))) {165 LOGGER.error("Do not generate screenshot for invalid driver!");166 // prevent recursive crash for onException167 return;168 }169 LOGGER.debug("DriverListener->onException starting..." + thr.getMessage());170 driver = castDriver(driver);171 try {172 // 1. if you see mess with afterTest carina actions and Timer startup failure you should follow steps #2+ to determine root cause.173 // Driver initialization 'default' FAILED! Retry 1 of 1 time - Operation already started: mobile_driverdefault174 // 2. carefully track all preliminary exception for the same thread to detect 1st problematic exception175 // 3. 99% those root exception means that we should prohibit screenshot generation for such use-case176 // 4. if 3rd one is true just update Screenshot.isCaptured() adding part of the exception to the list177 // handle cases which should't be captured178 if (Screenshot.isCaptured(thr.getMessage())) {179 captureScreenshot(thr.getMessage(), driver, null, true);180 }181 } catch (Exception e) {182 if (!e.getMessage().isEmpty()183 && (e.getMessage().contains("Method has not yet been implemented") || (e.getMessage().contains("Method is not implemented")))) {184 LOGGER.debug("Unrecognized exception detected in DriverListener->onException!", e);185 } else {186 LOGGER.error("Unrecognized exception detected in DriverListener->onException!", e);187 }188 } catch (Throwable e) {189 LOGGER.error("Take a look to the logs above for current thread and add exception into the exclusion for Screenshot.isCaptured().", e);190 }191 LOGGER.debug("DriverListener->onException finished.");192 }193 /**194 * Converts char sequence to string.195 * 196 * @param csa - char sequence array197 * @return string representation198 */199 private String charArrayToString(CharSequence[] csa) {200 String s = StringUtils.EMPTY;201 if (csa != null) {202 StringBuilder sb = new StringBuilder();203 for (CharSequence cs : csa) {204 sb.append(String.valueOf(cs));205 }206 s = sb.toString();207 }208 return s;209 }210 @Override211 public void afterSwitchToWindow(String arg0, WebDriver driver) {212 // do nothing213 }214 @Override215 public void beforeSwitchToWindow(String arg0, WebDriver driver) {216 // Do nothing217 }218 @Override219 public <X> void afterGetScreenshotAs(OutputType<X> arg0, X arg1) {220 // do nothing221 }222 @Override223 public <X> void beforeGetScreenshotAs(OutputType<X> arg0) {224 // Do nothing225 }226 @Override227 public void afterGetText(WebElement element, WebDriver driver, String arg2) {228 // do nothing229 }230 @Override231 public void beforeGetText(WebElement element, WebDriver driver) {232 // do nothing233 }234 private void captureScreenshot(String comment, WebDriver driver, WebElement element, boolean errorMessage) {235 driver = castDriver(driver);236 if (getMessage(errorMessage) != null) {237 comment = getMessage(errorMessage);238 }239 try {240 if (errorMessage) {241 LOGGER.error(comment);242 String screenName = Screenshot.captureByRule(driver, comment, true); // in case of failure try full size if allowed243 // do not generate UI dump if no screenshot244 if (!screenName.isEmpty()) {245 generateDump(driver, screenName);246 }247 } else {248 LOGGER.info(comment);249 Screenshot.captureByRule(driver, comment);250 }251 } catch (Exception e) {252 LOGGER.debug("Unrecognized failure detected in DriverListener->captureScreenshot!", e);253 } finally {254 resetMessages();255 }256 }257 private void generateDump(WebDriver driver, String screenName) {258 // XML layout extraction259 File uiDumpFile = getDevice(driver).generateUiDump(screenName);260 if (uiDumpFile != null) {261 // use the same naming but with zip extension. Put into the test artifacts folder262 String dumpArtifact = ReportContext.getArtifactsFolder().getAbsolutePath() + "/" + screenName.replace(".png", ".zip");263 LOGGER.debug("UI Dump artifact: " + dumpArtifact);264 // build path to screenshot using name265 File screenFile = new File(ReportContext.getTestDir().getAbsolutePath() + "/" + screenName);266 // archive page source dump and screenshot both together267 FileManager.zipFiles(dumpArtifact, uiDumpFile, screenFile);268 Artifact.attachToTest("UI Dump artifact", new File(dumpArtifact));269 } else {270 LOGGER.debug("Dump file is empty.");271 }272 }273 private void onAfterAction(String comment, WebDriver driver) {274 captureScreenshot(comment, driver, null, false);275 }276 public static String getMessage(boolean errorMessage) {277 if (errorMessage) {278 return currentNegativeMessage.get();279 } else {280 return currentPositiveMessage.get();281 }282 }283 public static void setMessages(String positiveMessage, String negativeMessage) {284 currentPositiveMessage.set(positiveMessage);285 currentNegativeMessage.set(negativeMessage);286 }287 private void resetMessages() {288 currentPositiveMessage.remove();289 currentNegativeMessage.remove();290 }291 /**292 * Cast Carina driver to WebDriver removing all extra listeners (try to avoid direct operations via WebDriver as it doesn't support logging etc)293 *294 * @param drv WebDriver295 *296 * @return WebDriver297 */298 private WebDriver castDriver(WebDriver drv) {299 if (drv instanceof EventFiringWebDriver) {300 drv = ((EventFiringWebDriver) drv).getWrappedDriver();301 }302 return drv;303 }304}...

Full Screen

Full Screen

castDriver

Using AI Code Generation

copy

Full Screen

1import com.qaprosoft.carina.core.foundation.webdriver.IDriverPool;2import com.qaprosoft.carina.core.foundation.webdriver.core.capability.impl.desktop.ChromeCapability;3import com.qaprosoft.carina.core.foundation.webdriver.core.capability.impl.desktop.FirefoxCapability;4import com.qaprosoft.carina.core.foundation.webdriver.core.capability.impl.desktop.IECapability;5import com.qaprosoft.carina.core.foundation.webdriver.core.capability.impl.desktop.OperaCapability;6import com.qaprosoft.carina.core.foundation.webdriver.core.capability.impl.mobile.AndroidCapability;7import com.qaprosoft.carina.core.foundation.webdriver.core.capability.impl.mobile.IOSCapability;8import com.qaprosoft.carina.core.foundation.webdriver.core.capability.impl.mobile.SafariCapability;9import com.qaprosoft.carina.core.foundation.webdriver.core.capability.impl.mobile.SafariMobileCapability;10import com.qaprosoft.carina.core.foundation.webdriver.core.capability.impl.mobile.SafariTabletCapability;11import com.qaprosoft.carina.core.foundation.webdriver.core.capability.impl.mobile.SafariiPadCapability;12import com.qaprosoft.carina.core.foundation.webdriver.core.capability.impl.mobile.SafariiPhoneCapability;13import com.qaprosoft.carina.core.foundation.webdriver.core.factory.impl.desktop.ChromeFactory;14import com.qaprosoft.carina.core.foundation.webdriver.core.factory.impl.desktop.FirefoxFactory;15import com.qaprosoft.carina.core.foundation.webdriver.core.factory.impl.desktop.IEFactory;16import com.qaprosoft.carina.core.foundation.webdriver.core.factory.impl.desktop.OperaFactory;17import com.qaprosoft.carina.core.foundation.webdriver.core.factory.impl.mobile.AndroidFactory;18import com.qaprosoft.carina.core.foundation.webdriver.core.factory.impl.mobile.IOSFactory;19import com.qaprosoft.carina.core.foundation.webdriver.core.factory.impl.mobile.SafariFactory;20import com.qaprosoft.carina.core.foundation.webdriver.core.factory.impl.mobile.SafariMobileFactory;21import com.qaprosoft.carina.core.foundation.webdriver.core.factory.impl.mobile.SafariTabletFactory;22import com.qaprosoft.carina.core.foundation.webdriver.core.factory.impl.mobile.SafariiPadFactory;23import com.qaprosoft.carina.core.foundation.webdriver.core.factory.impl.mobile.SafariiPhoneFactory;24import com.qaprosoft.carina.core.foundation.webdriver.device.Device;25import com.qaprosoft.carina.core.foundation.webdriver.device.DevicePool;26public class CastDriver {27public static void main(String[] args) {28 Device d = DevicePool.getDevice("iOS", "iPhone 6", "iOS

Full Screen

Full Screen

castDriver

Using AI Code Generation

copy

Full Screen

1import com.qaprosoft.carina.core.foundation.webdriver.IDriverPool;2import com.qaprosoft.carina.core.foundation.webdriver.core.capability.impl.desktop.ChromeCapability;3import com.qaprosoft.carina.core.foundation.webdriver.core.capability.impl.desktop.FirefoxCapability;4import com.qaprosoft.carina.core.foundation.webdriver.core.capability.impl.desktop.OperaCapability;5import com.qaprosoft.carina.core.foundation.webdriver.core.capability.impl.desktop.SafariCapability;6import com.qaprosoft.carina.core.foundation.webdriver.core.capability.impl.mobile.AndroidCapability;7import com.qaprosoft.carina.core.foundation.webdriver.core.capability.impl.mobile.IOSCapability;8import com.qaprosoft.carina.core.foundation.webdriver.core.capability.impl.mobile.SafariMobileCapability;9import com.qaprosoft.carina.core.foundation.webdriver.core.capability.impl.mobile.SafariTabletCapability;10import com.qaprosoft.carina.core.foundation.webdriver.core.capability.impl.mobile.SafariWatchCapability;11import com.qaprosoft.carina.core.foundation.webdriver.core.capability.impl.mobile.SafariiPadCapability;12import com.qaprosoft.carina.core.foundation.webdriver.core.capability.impl.mobile.SafariiPhoneCapability;13import com.qaprosoft.carina.core.foundation.webdriver.core.capability.impl.mobile.SafariiPodCapability;14import com.qaprosoft.carina.core.foundation.webdriver.core.capability.impl.mobile.ios.IOSiPhoneCapability;15import com.qaprosoft.carina.core.foundation.webdriver.core.capability.impl.mobile.ios.IOSiPadCapability;16import com.qaprosoft.carina.core.foundation.webdriver.core.capability.impl.mobile.ios.IOSiPodCapability;17import com.qaprosoft.carina.core.foundation.webdriver.core.capability.impl.mobile.ios.IOSiPhoneSimulatorCapability;18import com.qaprosoft.carina.core.foundation.webdriver.core.capability.impl.mobile.ios.IOSiPadSimulatorCapability;19import com.qaprosoft.carina.core.foundation.webdriver.core.capability.impl.mobile.ios.IOSiPodSimulatorCapability;20import com.qaprosoft.carina.core.foundation.webdriver.core.capability.impl.mobile.ios.IOSiPhoneXCapability;21import com.qaprosoft.carina.core.foundation.webdriver.core.capability.impl.mobile.ios.IOSiPhoneXSimulatorCapability;22import com.qaprosoft.carina.core.foundation.webdriver.core.capability.impl.mobile.ios.IOSiPhoneXRCapability;23import com.qaprosoft.carina.core.foundation.webdriver.core.capability.impl.mobile.ios.IOSiPhoneXRSimulatorCapability;24import com.qaprosoft.carina.core.foundation.webdriver

Full Screen

Full Screen

castDriver

Using AI Code Generation

copy

Full Screen

1import com.qaprosoft.carina.core.foundation.webdriver.IDriverPool;2import org.openqa.selenium.WebDriver;3import org.openqa.selenium.chrome.ChromeDriver;4public class 1 {5 public static void main(String[] args) {6 WebDriver driver = new ChromeDriver();7 IDriverPool.castDriver(driver, "chrome");8 }9}10import com.qaprosoft.carina.core.foundation.webdriver.IDriverPool;11import org.openqa.selenium.WebDriver;12import org.openqa.selenium.chrome.ChromeDriver;13public class 2 {14 public static void main(String[] args) {15 WebDriver driver = new ChromeDriver();16 IDriverPool.getDriver();17 }18}19import com.qaprosoft.carina.core.foundation.webdriver.IDriverPool;20import org.openqa.selenium.WebDriver;21import org.openqa.selenium.chrome.ChromeDriver;22public class 3 {23 public static void main(String[] args) {24 WebDriver driver = new ChromeDriver();25 IDriverPool.getDriver("chrome");26 }27}28import com.qaprosoft.carina.core.foundation.webdriver.IDriverPool;29import org.openqa.selenium.WebDriver;30import org.openqa.selenium.chrome.ChromeDriver;31public class 4 {32 public static void main(String[] args) {33 WebDriver driver = new ChromeDriver();34 IDriverPool.getDriver("chrome", "79.0");35 }36}37import com.qaprosoft.carina.core.foundation.webdriver.IDriverPool;38import org.openqa.selenium.WebDriver;39import org.openqa.selenium.chrome.ChromeDriver;40public class 5 {41 public static void main(String[] args) {42 WebDriver driver = new ChromeDriver();43 IDriverPool.getDriver("chrome", "79.0", "linux");44 }45}

Full Screen

Full Screen

castDriver

Using AI Code Generation

copy

Full Screen

1import com.qaprosoft.carina.core.foundation.webdriver.IDriverPool;2public class castDriver {3 public static void main(String[] args) {4 IDriverPool cast = new IDriverPool();5 cast.castDriver();6 }7}8import com.qaprosoft.carina.core.foundation.webdriver.IDriverPool;9public class castDriver {10 public static void main(String[] args) {11 IDriverPool cast = new IDriverPool();12 cast.castDriver();13 }14}15import com.qaprosoft.carina.core.foundation.webdriver.IDriverPool;16public class castDriver {17 public static void main(String[] args) {18 IDriverPool cast = new IDriverPool();19 cast.castDriver();20 }21}22import com.qaprosoft.carina.core.foundation.webdriver.IDriverPool;23public class castDriver {24 public static void main(String[] args) {25 IDriverPool cast = new IDriverPool();26 cast.castDriver();27 }28}29import com.qaprosoft.carina.core.foundation.webdriver.IDriverPool;30public class castDriver {31 public static void main(String[] args) {32 IDriverPool cast = new IDriverPool();33 cast.castDriver();34 }35}36import com.qaprosoft.carina.core.foundation.webdriver.IDriverPool;37public class castDriver {38 public static void main(String[] args) {39 IDriverPool cast = new IDriverPool();40 cast.castDriver();41 }42}43import com.qaprosoft.carina.core.foundation.webdriver.IDriverPool;44public class castDriver {45 public static void main(String[] args) {

Full Screen

Full Screen

castDriver

Using AI Code Generation

copy

Full Screen

1package com.qaprosoft.carina.demo;2import org.openqa.selenium.WebDriver;3import org.testng.Assert;4import org.testng.annotations.Test;5import com.qaprosoft.carina.core.foundation.webdriver.IDriverPool;6public class DemoTest {7 public void testDemo() throws Exception {8 WebDriver driver = IDriverPool.getDefaultDriver();9 Assert.assertTrue(driver.getTitle().contains("Google"), "Google page title doesn't contain 'Google' text!");10 }11}

Full Screen

Full Screen

castDriver

Using AI Code Generation

copy

Full Screen

1public class Test {2 public static void main(String[] args) {3 WebDriver driver = DriverPool.getDriver();4 RemoteWebDriver remoteWebDriver = (RemoteWebDriver) driver;5 String browserName = remoteWebDriver.getCapabilities().getBrowserName();6 System.out.println(browserName);7 }8}9public class Test {10 public static void main(String[] args) {11 WebDriver driver = DriverPool.getDriver();12 RemoteWebDriver remoteWebDriver = IDriverPool.castDriver(driver, RemoteWebDriver.class);13 String browserName = remoteWebDriver.getCapabilities().getBrowserName();14 System.out.println(browserName);15 }16}17public class Test {18 public static void main(String[] args) {19 WebDriver driver = DriverPool.getDriver();20 RemoteWebDriver remoteWebDriver = IDriverPool.castDriver(driver, RemoteWebDriver.class);21 String browserName = remoteWebDriver.getCapabilities().getBrowserName();22 System.out.println(browserName);23 }24}25public class Test {26 public static void main(String[] args) {27 WebDriver driver = DriverPool.getDriver();28 RemoteWebDriver remoteWebDriver = IDriverPool.castDriver(driver, RemoteWebDriver.class);29 String browserName = remoteWebDriver.getCapabilities().getBrowserName();30 System.out.println(browserName);31 }32}33public class Test {34 public static void main(String[] args) {35 WebDriver driver = DriverPool.getDriver();36 RemoteWebDriver remoteWebDriver = IDriverPool.castDriver(driver, RemoteWebDriver.class);37 String browserName = remoteWebDriver.getCapabilities().getBrowserName();38 System.out.println(browserName);

Full Screen

Full Screen

castDriver

Using AI Code Generation

copy

Full Screen

1IDriverPool castDriver = new com.qaprosoft.carina.core.foundation.webdriver.IDriverPool();2WebDriver driver = castDriver.getDriver("chrome");3WebDriver driver = castDriver.getDriver("firefox");4WebDriver driver = castDriver.getDriver("safari");5WebDriver driver = castDriver.getDriver("edge");6WebDriver driver = castDriver.getDriver("ie");7WebDriver driver = castDriver.getDriver("opera");8WebDriver driver = castDriver.getDriver("phantomjs");9DriverPool castDriver = new com.qaprosoft.carina.core.foundation.webdriver.DriverPool();10WebDriver driver = castDriver.getDriver("chrome");11WebDriver driver = castDriver.getDriver("firefox");12WebDriver driver = castDriver.getDriver("safari");13WebDriver driver = castDriver.getDriver("edge");

Full Screen

Full Screen

castDriver

Using AI Code Generation

copy

Full Screen

1public class 1 {2public static void main(String[] args) {3IDriverPool pool = new IDriverPool();4WebDriver driver = pool.castDriver();5}6}

Full Screen

Full Screen

Automation Testing Tutorials

Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.

LambdaTest Learning Hubs:

YouTube

You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Run Carina automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful