Skip to content

Commit dfa023b

Browse files
authored
feat(java): ✨ added support to run on lambdatest cloud (#205)
1 parent 96fba71 commit dfa023b

File tree

12 files changed

+767
-584
lines changed

12 files changed

+767
-584
lines changed

.github/workflows/test-core.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ jobs:
5555
LT_USER: ${{ secrets.LT_USER }}
5656
LT_KEY: ${{ secrets.LT_KEY }}
5757
BS_APP_ANDROID: ${{ secrets.BS_APP_ANDROID }}
58+
LT_APP_ANDROID: ${{ secrets.LT_APP_ANDROID }}
5859
steps:
5960
- name: Check out Git repository
6061
uses: actions/checkout@v3

.husky/commit-msg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@
33

44
yarn lint-staged
55
yarn build:site
6-
mvn org.jacoco:jacoco-maven-plugin:prepare-agent install -f core-java/pom.xml -Pcoverage-per-test -Dsuite-xml=test-suites/testng-local-husky.xml
6+
mvn clean install -f core-java/pom.xml -DskipTests

core-java/src/main/java/com/github/wasiqb/boyka/manager/DriverManager.java

Lines changed: 41 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
package com.github.wasiqb.boyka.manager;
1818

1919
import static com.github.wasiqb.boyka.enums.AutomationType.UI_AUTOMATOR;
20-
import static com.github.wasiqb.boyka.enums.CloudProviders.BROWSER_STACK;
2120
import static com.github.wasiqb.boyka.enums.CloudProviders.NONE;
2221
import static com.github.wasiqb.boyka.enums.DeviceType.CLOUD;
2322
import static com.github.wasiqb.boyka.enums.DeviceType.VIRTUAL;
@@ -46,14 +45,17 @@
4645
import static io.github.bonigarcia.wdm.WebDriverManager.edgedriver;
4746
import static io.github.bonigarcia.wdm.WebDriverManager.firefoxdriver;
4847
import static io.github.bonigarcia.wdm.WebDriverManager.safaridriver;
48+
import static java.lang.System.getProperty;
4949
import static java.text.MessageFormat.format;
5050
import static java.time.Duration.ofSeconds;
5151
import static java.util.Objects.requireNonNullElse;
52+
import static org.apache.commons.lang3.StringUtils.isNotEmpty;
5253
import static org.apache.logging.log4j.LogManager.getLogger;
5354

5455
import java.net.MalformedURLException;
5556
import java.net.URL;
5657
import java.nio.file.Path;
58+
import java.util.HashMap;
5759

5860
import com.github.wasiqb.boyka.config.FrameworkSetting;
5961
import com.github.wasiqb.boyka.config.ui.TimeoutSetting;
@@ -178,11 +180,13 @@ private URL getRemoteUrl (final WebSetting webSetting) {
178180

179181
private void setAndroidApplicationOptions (final UiAutomator2Options options,
180182
final ApplicationSetting application) {
181-
if (!application.isExternal ()) {
182-
options.setApp (Path.of (System.getProperty ("user.dir"), "/src/test/resources", application.getPath ())
183-
.toString ());
184-
} else {
185-
options.setApp (interpolate (application.getPath ()));
183+
if (isNotEmpty (application.getPath ())) {
184+
if (!application.isExternal ()) {
185+
options.setApp (Path.of (getProperty ("user.dir"), "/src/test/resources", application.getPath ())
186+
.toString ());
187+
} else {
188+
options.setApp (interpolate (application.getPath ()));
189+
}
186190
}
187191
options.setAppWaitActivity (application.getWaitActivity ());
188192
options.setAppWaitDuration (ofSeconds (application.getWaitTimeout ()));
@@ -284,12 +288,6 @@ private void setupAppiumServer () {
284288
.startServer ();
285289
}
286290

287-
private void setupBSAndroidDriver (final UiAutomator2Options options, final DeviceSetting deviceSetting) {
288-
if (deviceSetting.getCapabilities () != null) {
289-
options.setCapability ("bstack:options", deviceSetting.getCapabilities ());
290-
}
291-
}
292-
293291
private WebDriver setupChromeDriver (final WebSetting webSetting) {
294292
LOGGER.traceEntry ();
295293
chromedriver ().setup ();
@@ -302,6 +300,35 @@ private WebDriver setupChromeDriver (final WebSetting webSetting) {
302300
return LOGGER.traceExit (new ChromeDriver (options));
303301
}
304302

303+
private void setupCloudAndroidDriver (final UiAutomator2Options options, final ServerSetting serverSetting,
304+
final DeviceSetting deviceSetting) {
305+
switch (serverSetting.getCloud ()) {
306+
case BROWSER_STACK:
307+
setupCloudAndroidDriverOptions (options, deviceSetting, "bstack");
308+
break;
309+
case LAMBDA_TEST:
310+
default:
311+
setupCloudAndroidDriverOptions (options, deviceSetting, "lt");
312+
break;
313+
}
314+
}
315+
316+
private void setupCloudAndroidDriverOptions (final UiAutomator2Options options, final DeviceSetting deviceSetting,
317+
final String optionPrefix) {
318+
final var capabilities = deviceSetting.getCapabilities ();
319+
if (capabilities != null) {
320+
final var optionCapabilities = new HashMap<String, Object> ();
321+
capabilities.forEach ((k, v) -> {
322+
if (v instanceof String) {
323+
optionCapabilities.put (k, interpolate (v.toString ()));
324+
} else {
325+
optionCapabilities.put (k, v);
326+
}
327+
});
328+
options.setCapability (format ("{0}:options", optionPrefix), optionCapabilities);
329+
}
330+
}
331+
305332
private void setupDriver () {
306333
LOGGER.traceEntry ();
307334
if (this.platformType == API) {
@@ -353,8 +380,8 @@ private WebDriver setupSafariDriver () {
353380
private void setupUiAutomatorDriver (final ServerSetting serverSetting, final DeviceSetting deviceSetting) {
354381
final UiAutomator2Options options = new UiAutomator2Options ();
355382
setCommonUiAutomatorOptions (options, deviceSetting);
356-
if (deviceSetting.getType () == CLOUD && serverSetting.getCloud () == BROWSER_STACK) {
357-
setupBSAndroidDriver (options, deviceSetting);
383+
if (deviceSetting.getType () == CLOUD) {
384+
setupCloudAndroidDriver (options, serverSetting, deviceSetting);
358385
} else {
359386
setLocalUiAutomatorOptions (options, deviceSetting);
360387
}

core-java/src/main/java/com/github/wasiqb/boyka/manager/ServiceManager.java

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
package com.github.wasiqb.boyka.manager;
1818

1919
import static com.github.wasiqb.boyka.enums.CloudProviders.NONE;
20-
import static com.github.wasiqb.boyka.enums.Message.ERROR_DELETING_LOGS;
2120
import static com.github.wasiqb.boyka.enums.Message.ERROR_SERVER_NOT_RUNNING;
2221
import static com.github.wasiqb.boyka.enums.Message.ERROR_STARTING_SERVER;
2322
import static com.github.wasiqb.boyka.enums.Message.ERROR_STOPPING_SERVER;
@@ -36,8 +35,6 @@
3635
import static java.lang.Thread.currentThread;
3736
import static java.text.MessageFormat.format;
3837
import static java.time.Duration.ofSeconds;
39-
import static org.apache.commons.io.FileUtils.cleanDirectory;
40-
import static org.apache.commons.io.FileUtils.isEmptyDirectory;
4138
import static org.apache.commons.lang3.StringUtils.isNoneEmpty;
4239
import static org.apache.commons.lang3.StringUtils.isNotEmpty;
4340
import static org.apache.logging.log4j.LogManager.getLogger;
@@ -240,26 +237,18 @@ private void setLogArguments () {
240237
}
241238

242239
private void setLogFile () {
243-
final String logFolderPath = this.setting.getLogs ()
240+
final var logFolderPath = this.setting.getLogs ()
244241
.getPath ();
245242
if (logFolderPath != null) {
246-
final File logFolder = new File (logFolderPath);
247-
try {
248-
if (!isEmptyDirectory (logFolder)) {
249-
cleanDirectory (logFolder);
250-
}
251-
} catch (final IOException e) {
252-
handleAndThrow (ERROR_DELETING_LOGS, e);
253-
}
254243
final var filePath = new File (format ("{0}/server-{1}.log", logFolderPath, currentThread ().getId ()));
255244
this.builder.withLogFile (filePath);
256245
}
257246
}
258247

259248
private void setNodeExe () {
260249
if (this.setting.getNodePath () != null) {
261-
final File nde = new File (this.setting.getNodePath ());
262-
this.builder.usingDriverExecutable (nde);
250+
final var node = new File (this.setting.getNodePath ());
251+
this.builder.usingDriverExecutable (node);
263252
}
264253
}
265254

core-java/src/main/java/com/github/wasiqb/boyka/sessions/DriverSession.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,7 @@
2222
import com.github.wasiqb.boyka.config.FrameworkSetting;
2323
import com.github.wasiqb.boyka.enums.PlatformType;
2424
import com.github.wasiqb.boyka.manager.ServiceManager;
25-
import lombok.Getter;
26-
import lombok.Setter;
25+
import lombok.Data;
2726
import org.apache.logging.log4j.Logger;
2827
import org.openqa.selenium.WebDriver;
2928
import org.openqa.selenium.support.ui.WebDriverWait;
@@ -36,10 +35,10 @@
3635
* @author Wasiq Bhamla
3736
* @since 19-Feb-2022
3837
*/
39-
@Setter
40-
@Getter
38+
@Data
4139
public class DriverSession<D extends WebDriver> {
4240
private static final Logger LOGGER = getLogger ();
41+
4342
private D driver;
4443
private PlatformType platformType;
4544
private ServiceManager serviceManager;

core-java/src/test/resources/boyka-config.json

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,41 @@
197197
"appiumLogs": true
198198
}
199199
}
200+
},
201+
"test_lt_android": {
202+
"server": {
203+
"cloud": "LAMBDA_TEST",
204+
"protocol": "HTTPS",
205+
"host": "mobile-hub.lambdatest.com",
206+
"user_name": "${env:LT_USER}",
207+
"password": "${env:LT_KEY}",
208+
"base_path": "/wd/hub"
209+
},
210+
"device": {
211+
"automation": "UI_AUTOMATOR",
212+
"type": "CLOUD",
213+
"application": {
214+
"wait_activity": "com.swaglabsmobileapp.MainActivity",
215+
"install_timeout": 180
216+
},
217+
"capabilities": {
218+
"platformName": "Android",
219+
"deviceName": "Pixel 5",
220+
"platformVersion": "11",
221+
"app": "${env:LT_APP_ANDROID}",
222+
"project": "LambdaTest Android Project",
223+
"build": "Test LambdaTest Build",
224+
"name": "Test LambdaTest Session",
225+
"devicelog": true,
226+
"network": true,
227+
"visual": true,
228+
"video": true,
229+
"autoGrantPermissions": true,
230+
"autoAcceptAlerts": true,
231+
"isRealMobile": true,
232+
"w3c": true
233+
}
234+
}
200235
}
201236
}
202237
},
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
~ MIT License
4+
~
5+
~ Copyright (c) 2022 Wasiq Bhamla
6+
~
7+
~ Permission is hereby granted, free of charge, to any person obtaining a copy
8+
~ of this software and associated documentation files (the "Software"), to deal
9+
~ in the Software without restriction, including without limitation the rights
10+
~ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
~ copies of the Software, and to permit persons to whom the Software is
12+
~ furnished to do so, subject to the following conditions:
13+
~
14+
~ The above copyright notice and this permission notice shall be included in all
15+
~ copies or substantial portions of the Software.
16+
-->
17+
18+
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
19+
<suite name="Boyka Mobile Cloud Suite" verbose="2" parallel="classes">
20+
<test name="Test Boyka Mobile on LambdaTest Android Device">
21+
<parameter name="appType" value="ANDROID"/>
22+
<parameter name="driverKey" value="test_lt_android"/>
23+
<packages>
24+
<package name="com.github.wasiqb.boyka.testng.mobile"/>
25+
</packages>
26+
</test>
27+
</suite>

core-java/test-suites/testng-mobile.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,6 @@
2020
<suite-files>
2121
<suite-file path="testng-mobile-local.xml"/>
2222
<suite-file path="testng-mobile-bs.xml"/>
23+
<suite-file path="testng-mobile-lt.xml"/>
2324
</suite-files>
2425
</suite>

package.json

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,29 +32,29 @@
3232
"devDependencies": {
3333
"@commitlint/cli": "^17.1.2",
3434
"@commitlint/config-conventional": "^17.1.0",
35-
"@types/node": "^18.7.18",
36-
"@typescript-eslint/eslint-plugin": "^5.38.0",
37-
"@typescript-eslint/parser": "^5.38.0",
35+
"@types/node": "^18.8.0",
36+
"@typescript-eslint/eslint-plugin": "^5.38.1",
37+
"@typescript-eslint/parser": "^5.38.1",
3838
"commitlint": "^17.1.2",
39-
"eslint": "^8.23.1",
39+
"eslint": "^8.24.0",
4040
"eslint-config-google": "^0.14.0",
4141
"eslint-config-prettier": "^8.5.0",
4242
"eslint-import-resolver-typescript": "^3.5.1",
4343
"eslint-plugin-import": "^2.26.0",
4444
"eslint-plugin-prettier": "^4.2.1",
4545
"eslint-plugin-react": "^7.31.8",
4646
"husky": "^8.0.1",
47-
"lerna": "^5.5.1",
47+
"lerna": "^5.6.1",
4848
"lerna-changelog": "^2.2.0",
4949
"lint-staged": "^13.0.3",
5050
"prettier": "^2.7.1",
5151
"react": "^18.2.0",
5252
"react-dom": "^18.2.0",
5353
"ts-node": "^10.9.1",
54-
"typescript": "^4.8.3"
54+
"typescript": "^4.8.4"
5555
},
5656
"scripts": {
57-
"prepare": "husky install",
57+
"postinstall": "husky install",
5858
"build:site": "yarn workspace website build",
5959
"start:site": "yarn workspace website start",
6060
"deploy:site": "yarn workspace website deploy",

website/docs/contributing/project-details/commit-steps.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ Following checks will happen when you commit:
153153
- ESLint to check if the website code complies with the [ESLint](https://eslint.org/) rules. It will only run if there is change to `.js`, `.jsx`, `.ts` or `.tsx` files.
154154
- Prettier to check if the website code complies with the [Prettier](https://prettier.io/) rules. It will only run if there is change to `.js`, `.jsx`, `.ts` or `.tsx` files.
155155
- Build the documentation website to check if the website builds successfully.
156-
- Build and run tests from the Java project to check if the check style, code compilation is successful and overall code coverage is above `70%`.
156+
- Build and run check styles from the Java project to check if the check style and code compilation is successful.
157157

158158
## Push your commit
159159

@@ -173,4 +173,8 @@ When you click on the `Push` button, you will see a pop-up asking you to confirm
173173

174174
## Create draft PR
175175

176-
As soon as you push your commit, you must create a draft PR on GitHub. Because our workflows will only get triggered on PR's that are raised against `main` branch.
176+
As soon as you push your commit, you must create a draft PR on GitHub. Because our workflows will only get triggered on PR's that are raised against `develop` branch.
177+
178+
## Ping on Discord
179+
180+
Once PR is raised, ping in the `#contributor-discussion` channel on our [Discord server](https://discord.gg/dUg8K9DAsR) to let all the contributors know and you can schedule a demo with the contributors to showcase your changes.

0 commit comments

Comments
 (0)