Skip to content

Commit d5ef515

Browse files
authored
Execute script and Android startActivity action +semver: feature (#52)
* Update to Appium 9.5.0 and Selenium 4.33.0 +semver:feature * Execute script and Android startActivity action +semver: feature Update Selenium reference to v.4.34.0 Update license year
1 parent e8f8f93 commit d5ef515

File tree

16 files changed

+135
-25
lines changed

16 files changed

+135
-25
lines changed

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@
186186
same "printed page" as the copyright notice for easier
187187
identification within third-party archives.
188188

189-
Copyright 2024 Aquality Automation
189+
Copyright 2025 Aquality Automation
190190

191191
Licensed under the Apache License, Version 2.0 (the "License");
192192
you may not use this file except in compliance with the License.

azure-pipelines.yml

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,37 +9,39 @@ jobs:
99
displayName: Analyse code with SonarQube
1010

1111
steps:
12-
- task: SonarCloudPrepare@1
12+
- task: SonarCloudPrepare@3
1313
displayName: 'Prepare SonarCloud analysis'
1414
inputs:
1515
SonarCloud: 'SonarCloud'
1616
organization: 'aqualityautomation'
1717
scannerMode: 'CLI'
1818
configMode: 'file'
19-
extraProperties: |
20-
sonar.coverage.exclusions=**/**
19+
extraProperties: 'sonar.coverage.exclusions=**/**'
2120

22-
- task: Maven@3
21+
- task: Maven@4
2322
displayName: 'Compile project'
2423
inputs:
2524
mavenPomFile: 'pom.xml'
26-
goals: 'clean compile'
25+
goals: 'clean'
2726
publishJUnitResults: true
2827
testResultsFiles: '**/surefire-reports/TEST-*.xml'
2928
javaHomeOption: 'JDKVersion'
30-
jdkVersionOption: '11'
29+
jdkVersionOption: '1.11'
3130
mavenVersionOption: 'Default'
3231
mavenAuthenticateFeed: false
3332
effectivePomSkip: false
3433
sonarQubeRunAnalysis: false
35-
continueOnError: true
3634

37-
- task: SonarCloudAnalyze@1
35+
- task: SonarCloudAnalyze@3
36+
inputs:
37+
jdkversion: 'JAVA_HOME_21_X64'
3838
displayName: 'Run SonarCloud code analysis'
3939
continueOnError: true
4040

41-
- task: SonarCloudPublish@1
41+
- task: SonarCloudPublish@3
4242
displayName: 'Publish SonarCloud quality gate results'
43+
inputs:
44+
pollingTimeoutSec: '300'
4345

4446
- job: tests
4547
displayName: Run tests

pom.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@
184184
<dependency>
185185
<groupId>com.github.aquality-automation</groupId>
186186
<artifactId>aquality-selenium-core</artifactId>
187-
<version>4.6.0</version>
187+
<version>4.7.0</version>
188188
</dependency>
189189

190190
<dependency>
@@ -203,7 +203,7 @@
203203
<dependency>
204204
<groupId>org.apache.commons</groupId>
205205
<artifactId>commons-lang3</artifactId>
206-
<version>3.17.0</version>
206+
<version>3.18.0</version>
207207
<scope>test</scope>
208208
</dependency>
209209

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package aquality.appium.mobile.actions;
2+
3+
import aquality.appium.mobile.application.AqualityServices;
4+
import io.appium.java_client.android.AndroidDriver;
5+
6+
import java.util.HashMap;
7+
import java.util.Map;
8+
9+
public class AndroidActions implements IAndroidActions {
10+
@Override
11+
public void startActivity(String appPackage, String appActivity, boolean stopApp) {
12+
AqualityServices.getLocalizedLogger().info("loc.application.android.activity.start", appPackage, appActivity);
13+
Map<String, Object> args = new HashMap<>();
14+
args.put("intent", String.format("%s/%s", appPackage, appActivity));
15+
args.put("package", appPackage);
16+
args.put("stop", stopApp);
17+
AqualityServices.getApplication().executeScript("mobile: startActivity", args);
18+
AqualityServices.getConditionalWait().waitFor(
19+
driver -> appActivity.equals(((AndroidDriver)driver).currentActivity()),
20+
String.format("Activity %s was not started", appActivity));
21+
}
22+
}

src/main/java/aquality/appium/mobile/actions/IActionsModule.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,11 @@ public interface IActionsModule extends IConfigurationsModule {
1313
default Class<? extends ITouchActions> getTouchActionsImplementation() {
1414
return TouchActions.class;
1515
}
16+
17+
/**
18+
* @return class which implements {@link IAndroidActions}
19+
*/
20+
default Class<? extends IAndroidActions> getAndroidActionsImplementation() {
21+
return AndroidActions.class;
22+
}
1623
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package aquality.appium.mobile.actions;
2+
3+
import io.appium.java_client.android.Activity;
4+
5+
/**
6+
* Extensions for Android applications.
7+
*/
8+
public interface IAndroidActions {
9+
10+
/**
11+
* Starts application activity.
12+
* @param activity Activity to start.
13+
* @param stopApp True if you need to stop currently running application, false otherwise.
14+
*/
15+
default void startActivity(Activity activity, boolean stopApp) {
16+
startActivity(activity.getAppPackage(), activity.getAppActivity(), stopApp);
17+
}
18+
19+
/**
20+
* Starts application activity.
21+
* Currently running application will be stopped.
22+
* @param appPackage Package of the target application.
23+
* @param appActivity Target activity.
24+
*/
25+
default void startActivity(String appPackage, String appActivity) {
26+
startActivity(appPackage, appActivity, true);
27+
}
28+
29+
/**
30+
* Starts application activity.
31+
* @param appPackage Package of the target application.
32+
* @param appActivity Target activity.
33+
* @param stopApp True if you need to stop currently running application, false otherwise.
34+
*/
35+
void startActivity(String appPackage, String appActivity, boolean stopApp);
36+
}

src/main/java/aquality/appium/mobile/application/Application.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,14 +105,27 @@ protected void doWithRetry(Runnable function) {
105105
.doWithRetry(function, Collections.singletonList(WebDriverException.class));
106106
}
107107

108+
@Override
109+
public <T> T executeScript(String script, Map<String, Object> params) {
110+
return doWithRetry(() -> {
111+
String argsString = params == null || params.isEmpty() ? "" : ", " + params;
112+
localizedLogger.info("loc.application.execute.script", script + argsString);
113+
T result = CommandExecutionHelper.executeScript(getDriver().assertExtensionExists(script), script, params);
114+
if (result != null) {
115+
localizedLogger.info("loc.application.script.result", result);
116+
}
117+
return result;
118+
});
119+
}
120+
108121
@Override
109122
public String getId() {
110123
final String iosExtName = "mobile: activeAppInfo";
111124
return doWithRetry(() -> {
112125
if (PlatformName.ANDROID == getPlatformName()) {
113126
return ((AndroidDriver) getDriver()).getCurrentPackage();
114127
}
115-
Map<String, Object> result = CommandExecutionHelper.executeScript(getDriver().assertExtensionExists(iosExtName), iosExtName);
128+
Map<String, Object> result = executeScript(iosExtName, null);
116129
return String.valueOf(Objects.requireNonNull(result).get("bundleId"));
117130
});
118131
}

src/main/java/aquality/appium/mobile/application/AqualityServices.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package aquality.appium.mobile.application;
22

3+
import aquality.appium.mobile.actions.IAndroidActions;
34
import aquality.appium.mobile.actions.ITouchActions;
45
import aquality.appium.mobile.configuration.IApplicationProfile;
56
import aquality.appium.mobile.configuration.IConfiguration;
@@ -200,4 +201,13 @@ public static IConfiguration getConfiguration() {
200201
public static ITouchActions getTouchActions() {
201202
return get(ITouchActions.class);
202203
}
204+
205+
/**
206+
* Gets the utility used to perform Android-specific actions.
207+
*
208+
* @return instance of Android actions.
209+
*/
210+
public static IAndroidActions getAndroidActions() {
211+
return get(IAndroidActions.class);
212+
}
203213
}

src/main/java/aquality/appium/mobile/application/IMobileApplication.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
import org.openqa.selenium.remote.service.DriverService;
99

1010
import java.time.Duration;
11+
import java.util.Collections;
12+
import java.util.Map;
1113

1214
public interface IMobileApplication extends IApplication {
1315
/**
@@ -63,6 +65,23 @@ default InteractsWithApps appManagement() {
6365
*/
6466
ApplicationState getState(String appId);
6567

68+
/**
69+
* Execute application script
70+
* @param script script
71+
* @param params parameters
72+
* @return result of the script execution.
73+
*/
74+
<T> T executeScript(String script, Map<String, Object> params);
75+
76+
/**
77+
* Execute application script
78+
* @param script script
79+
* @return result of the script execution.
80+
*/
81+
default <T> T executeScript(String script) {
82+
return executeScript(script, Collections.emptyMap());
83+
}
84+
6685
/**
6786
* Installs an application.
6887
*

src/main/java/aquality/appium/mobile/application/MobileModule.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package aquality.appium.mobile.application;
22

33
import aquality.appium.mobile.actions.IActionsModule;
4+
import aquality.appium.mobile.actions.IAndroidActions;
45
import aquality.appium.mobile.actions.ITouchActions;
56
import aquality.appium.mobile.configuration.IApplicationProfile;
67
import aquality.appium.mobile.configuration.IConfiguration;
@@ -31,5 +32,6 @@ protected void configure() {
3132
bind(IScreenFactory.class).to(getScreenFactoryImplementation());
3233
bind(ITouchActionsConfiguration.class).to(getTouchActionsConfigurationImplementation());
3334
bind(ITouchActions.class).to(getTouchActionsImplementation());
35+
bind(IAndroidActions.class).to(getAndroidActionsImplementation());
3436
}
3537
}

0 commit comments

Comments
 (0)