Skip to content

Commit

Permalink
feature: new action switchToContext (#2408)
Browse files Browse the repository at this point in the history
  • Loading branch information
lucashimpens committed Sep 4, 2023
1 parent cf15b4a commit fbf7ce6
Show file tree
Hide file tree
Showing 9 changed files with 80 additions and 37 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ public class TestCaseStepAction {
public static final String ACTION_SETCONSOLECONTENT = "setConsoleContent";
public static final String ACTION_SETCONTENT = "setContent";
public static final String ACTION_SETSERVICECALLCONTENT = "setServiceCallContent";
public static final String ACTION_SWITCHTOCONTEXT = "switchToContext";
public static final String ACTION_DONOTHING = "doNothing";

// ??? TODO. Clean this unused action.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,10 @@
package org.cerberus.core.engine.gwt.impl;

import com.google.common.primitives.Ints;
import org.apache.commons.codec.binary.Base64;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.cerberus.core.crud.entity.AppService;
import org.cerberus.core.crud.entity.Application;
import org.cerberus.core.crud.entity.TestCaseCountryProperties;
import org.cerberus.core.crud.entity.TestCaseExecution;
import org.cerberus.core.crud.entity.TestCaseExecutionData;
import org.cerberus.core.crud.entity.TestCaseStepAction;
import org.cerberus.core.crud.entity.TestCaseStepActionExecution;
import org.cerberus.core.crud.entity.*;
import org.cerberus.core.crud.factory.IFactoryAppService;
import org.cerberus.core.crud.factory.IFactoryTestCaseExecutionData;
import org.cerberus.core.crud.service.IAppServiceService;
Expand All @@ -38,7 +33,6 @@
import org.cerberus.core.engine.entity.Identifier;
import org.cerberus.core.engine.entity.MessageEvent;
import org.cerberus.core.engine.entity.MessageGeneral;
import org.cerberus.core.service.appium.SwipeAction;
import org.cerberus.core.engine.execution.IIdentifierService;
import org.cerberus.core.engine.execution.IRecorderService;
import org.cerberus.core.engine.execution.IRobotServerService;
Expand All @@ -51,15 +45,17 @@
import org.cerberus.core.exception.CerberusEventException;
import org.cerberus.core.exception.CerberusException;
import org.cerberus.core.service.appium.IAppiumService;
import org.cerberus.core.service.appium.SwipeAction;
import org.cerberus.core.service.appservice.IServiceService;
import org.cerberus.core.service.cerberuscommand.ICerberusCommand;
import org.cerberus.core.service.consolelog.IConsolelogService;
import org.cerberus.core.service.har.IHarService;
import org.cerberus.core.service.har.entity.NetworkTrafficIndex;
import org.cerberus.core.service.rest.IRestService;
import org.cerberus.core.service.robotextension.ISikuliService;
import org.cerberus.core.service.robotextension.IFilemanagementService;
import org.cerberus.core.service.robotextension.ISikuliService;
import org.cerberus.core.service.robotextension.impl.SikuliService;
import org.cerberus.core.service.robotproxy.IRobotProxyService;
import org.cerberus.core.service.soap.ISoapService;
import org.cerberus.core.service.sql.ISQLService;
import org.cerberus.core.service.webdriver.IWebDriverService;
Expand All @@ -80,8 +76,6 @@
import java.util.Date;
import java.util.HashMap;
import java.util.Optional;
import org.apache.commons.codec.binary.Base64;
import org.cerberus.core.service.robotproxy.IRobotProxyService;

/**
* @author bcivel
Expand Down Expand Up @@ -345,6 +339,9 @@ public TestCaseStepActionExecution doAction(TestCaseStepActionExecution actionEx
case TestCaseStepAction.ACTION_SWITCHTOWINDOW:
res = this.doActionSwitchToWindow(execution, value1, value2);
break;
case TestCaseStepAction.ACTION_SWITCHTOCONTEXT:
res = this.doActionSwitchToContext(execution, value1);
break;
case TestCaseStepAction.ACTION_MANAGEDIALOG:
res = this.doActionManageDialog(execution, value1, value2);
break;
Expand Down Expand Up @@ -1046,6 +1043,19 @@ private MessageEvent doActionSwitchToWindow(TestCaseExecution tCExecution, Strin
}
}

private MessageEvent doActionSwitchToContext(TestCaseExecution tCExecution, String context) {
String applicationType = tCExecution.getApplicationObj().getType();
if (applicationType.equalsIgnoreCase(Application.TYPE_APK)) {
return androidAppiumService.switchToContext(tCExecution.getSession(), context);
} else if (applicationType.equalsIgnoreCase(Application.TYPE_IPA)) {
return iosAppiumService.switchToContext(tCExecution.getSession(), context);
} else {
return new MessageEvent(MessageEventEnum.ACTION_NOTEXECUTED_NOTSUPPORTED_FOR_APPLICATION)
.resolveDescription("ACTION", "SwitchToContext")
.resolveDescription("APPLICATIONTYPE", tCExecution.getApplicationObj().getType());
}
}

private MessageEvent doActionManageDialog(TestCaseExecution tCExecution, String value1, String value2) {
MessageEvent message;
String element;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ public enum MessageEventEnum {
ACTION_SUCCESS_MOUSEDOWN(200, "OK", "Mouse Left Click pressed on Element '%ELEMENT%'.", false, false, false, MessageGeneralEnum.EXECUTION_PE_TESTSTARTED),
ACTION_SUCCESS_MOUSEUP(200, "OK", "Mouse Left Click Released on Element '%ELEMENT%'.", false, false, false, MessageGeneralEnum.EXECUTION_PE_TESTSTARTED),
ACTION_SUCCESS_SWITCHTOWINDOW(200, "OK", "Focus of Selenium was changed to Window '%WINDOW%'", false, false, false, MessageGeneralEnum.EXECUTION_PE_TESTSTARTED),
ACTION_SUCCESS_SWITCHTOCONTEXT(200, "OK", "Context was successfully changed to %CONTEXT%.", false, false, false, MessageGeneralEnum.EXECUTION_PE_TESTSTARTED),
ACTION_SUCCESS_CLOSE_ALERT(200, "OK", "Alert popup is closed !", false, false, false, MessageGeneralEnum.EXECUTION_PE_TESTSTARTED),
ACTION_SUCCESS_KEYPRESS_ALERT(200, "OK", "Keypress '%KEY%' done on alert popup !", false, false, false, MessageGeneralEnum.EXECUTION_PE_TESTSTARTED),
ACTION_SUCCESS_CALLSOAP(200, "OK", "Call to SOAP Operation '%SOAPMETHOD%' on Service Path %SERVICEPATH% executed successfully and stored to memory!", false, false, false, MessageGeneralEnum.EXECUTION_PE_TESTSTARTED),
Expand Down Expand Up @@ -294,6 +295,7 @@ public enum MessageEventEnum {
ACTION_FAILED_MOUSEUP_NO_SUCH_ELEMENT(282, "FA", "Failed to release click because could not find element '%ELEMENT%'!", true, true, true, MessageGeneralEnum.EXECUTION_FA_ACTION),
ACTION_FAILED_MOUSEDOWN_NO_SUCH_ELEMENT(283, "FA", "Failed to left click because could not find element '%ELEMENT%'!", true, true, true, MessageGeneralEnum.EXECUTION_FA_ACTION),
ACTION_FAILED_SWITCHTOWINDOW_NO_SUCH_ELEMENT(280, "FA", "Failed to switch to window because could not find element '%WINDOW%'!", true, true, true, MessageGeneralEnum.EXECUTION_FA_ACTION),
ACTION_FAILED_SWITCHTOCONTEXT_NO_SUCH_ELEMENT(280, "FA", "Failed to switch to context '%CONTEXT%' because could not find it! Available contexts are: '%CONTEXTS%'. Detailed error: %ERROR%", true, true, true, MessageGeneralEnum.EXECUTION_FA_ACTION),
ACTION_FAILED_CLOSE_ALERT(280, "FA", "Failed to close the alert popup ! Please either specify 'ok' or 'cancel'.", true, true, true, MessageGeneralEnum.EXECUTION_FA_ACTION),
ACTION_FAILED_KEYPRESS_ALERT(280, "FA", "Failed to keypress '%KEY%' on the alert popup !", true, true, true, MessageGeneralEnum.EXECUTION_FA_ACTION),
ACTION_FAILED_CALLSERVICE_SEEKALLTOPICS(286, "FA", "Failed when getting latest offset of every topics. %DESCRIPTION%.", true, true, false, MessageGeneralEnum.EXECUTION_FA_ACTION),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,29 +25,32 @@
import org.cerberus.core.service.appium.SwipeAction.Direction;

/**
*
* @author bcivel
*/
public interface IAppiumService {

/**
*
* @param session
* @param identifier
* @return
*/
MessageEvent switchToContext(Session session, Identifier identifier);

/**
*
* @param session Appium session
* @param context Name of the context to switch to
* @return Message to inform of the action result
*/
MessageEvent switchToContext(Session session, String context);

/**
* @param session
* @param identifier
* @return
*/
MessageEvent wait(Session session, Identifier identifier);

/**
*
* @param session
* @param identifier
* @param valueToType
Expand All @@ -57,38 +60,33 @@ public interface IAppiumService {
MessageEvent type(Session session, Identifier identifier, String valueToType, String propertyName);

/**
*
* @param session
* @param identifier
* @return
*/
MessageEvent click(Session session, Identifier identifier);

/**
*
* @param session
* @param keyName
* @return
*/
MessageEvent keyPress(Session session, String keyName);

/**
*
* @param session
* @return
*/
MessageEvent hideKeyboard(Session session);

/**
*
* @param session
* @param swipeAction
* @return
*/
MessageEvent swipe(Session session, SwipeAction swipeAction);

/**
*
* @param session
* @param action
* @return
Expand All @@ -97,7 +95,6 @@ public interface IAppiumService {
Direction getDirectionForSwipe(Session session, SwipeAction action) throws IllegalArgumentException;

/**
*
* @param session
* @param cmd
* @param args
Expand All @@ -111,7 +108,7 @@ public interface IAppiumService {
*
* @param session
* @param element if not null or not empty, switch to this element
* @param text if not null or not empty, switch to this text
* @param text if not null or not empty, switch to this text
* @return
* @throws IllegalArgumentException
*/
Expand Down Expand Up @@ -156,7 +153,6 @@ public interface IAppiumService {
MessageEvent closeApp(Session session);

/**
*
* @param session
* @param identifier
* @param pressDuration
Expand All @@ -165,7 +161,6 @@ public interface IAppiumService {
MessageEvent longPress(Session session, Identifier identifier, Integer pressDuration);

/**
*
* @param session
* @param identifier
* @return
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,8 @@
*/
package org.cerberus.core.service.appium.impl;

import io.appium.java_client.AppiumDriver;
import io.appium.java_client.MobileBy;
import io.appium.java_client.MobileElement;
import io.appium.java_client.TouchAction;
import io.appium.java_client.NoSuchContextException;
import io.appium.java_client.*;
import io.appium.java_client.touch.WaitOptions;
import io.appium.java_client.touch.offset.ElementOption;
import io.appium.java_client.touch.offset.PointOption;
Expand All @@ -39,13 +37,7 @@
import org.cerberus.core.util.ParameterParserUtil;
import org.cerberus.core.util.StringUtil;
import org.json.JSONException;
import org.openqa.selenium.By;
import org.openqa.selenium.Dimension;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.Point;
import org.openqa.selenium.TimeoutException;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.*;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.springframework.beans.factory.annotation.Autowired;
Expand Down Expand Up @@ -102,6 +94,30 @@ public MessageEvent switchToContext(Session session, Identifier identifier) {
return message;
}

@Override
public MessageEvent switchToContext(Session session, String context) {
MessageEvent message;
AppiumDriver driver = session.getAppiumDriver();
Set<String> contexts = driver.getContextHandles();

try {
if (context.isEmpty()) {
context = "NATIVE_APP";
}
driver.context(context);
message = new MessageEvent(MessageEventEnum.ACTION_SUCCESS_SWITCHTOCONTEXT);
message.setDescription(message.getDescription().replace("%CONTEXT%", context));
} catch (NoSuchContextException exception) {
LOG.error("Impossible to change the context: ", exception);
message = new MessageEvent(MessageEventEnum.ACTION_FAILED_SWITCHTOCONTEXT_NO_SUCH_ELEMENT);
message.setDescription(message.getDescription()
.replace("%CONTEXT%", context)
.replace("%CONTEXTS%", contexts.toString())
.replace("%ERROR%", exception.getMessage()));
}
return message;
}

@Override
public MessageEvent wait(Session session, Identifier identifier) {
MessageEvent message;
Expand Down Expand Up @@ -201,11 +217,11 @@ private MessageEvent parseWebDriverException(WebDriverException exception) {
* Get the {@link Coordinates} represented by the given {@link Identifier}
*
* @param identifier the {@link Identifier} to parse to get the
* {@link Coordinates}
* {@link Coordinates}
* @return the {@link Coordinates} represented by the given
* {@link Identifier}
* @throws NoSuchElementException if no {@link Coordinates} can be found
* inside the given {@link Identifier}
* inside the given {@link Identifier}
*/
private Coordinates getCoordinates(final Identifier identifier) {
if (identifier == null || !identifier.isSameIdentifier(Identifier.Identifiers.COORDINATE)) {
Expand Down
4 changes: 4 additions & 0 deletions source/src/main/resources/database.sql
Original file line number Diff line number Diff line change
Expand Up @@ -6222,3 +6222,7 @@ INSERT INTO `parameter` (`system`, `param`, `value`, `description`)
VALUES ('', 'cerberus_instancelogo_url', 'https://vm.cerberus-testing.org/img/logo.png', 'URl that point to the instance logo. Use that parameter in order to personalize some screens and pdf report.'),
('', 'cerberus_pdfcampaignreportdisplaycountry_boolean', 'true', 'Boolean in order to show or hide the country column on pdf campaign execution pdf report.');

-- 1753
INSERT INTO `invariant` (`idname`, `value`, `sort`, `description`, `veryshortdesc`)
VALUES ('ACTION', 'switchToContext', 5450, 'Switch to another application context', 'switchToContext');

Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,18 @@ title=titleOfThisNewWindow
url=http://url_of_this_new_window
====

==== switchToContext
|===

| *[red]#GUI#* | *[red]#SRV#* | *[green]#APK#* | *[green]#IPA#* | *[red]#FAT#* | *[red]#BAT#*

|===
Switch the current application context to another.

*[blue]#Value1#* Name of the context you want to switch to. If the value is empty, this will switch to the default context "NATIVE_APP".
For example, you can set this action with defined value to switch on the context you want, then do your actions in this context, and finally set again
this action with no value to get back to the default context.

==== manageDialog
|===

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
* Support for MongoDB Service type.
* Added background on steps according to the status and displayed condition when step NE on TestcaseExecution page. #2463
* A pdf report is now available for campaign execution for download #2475
* New action "Switch To Context" #2408

*Warning to be considered before applying the version (deprecated features)*
[square]
Expand Down
2 changes: 2 additions & 0 deletions source/src/main/webapp/js/testcase/action.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit fbf7ce6

Please sign in to comment.