Skip to content

Commit 4c6e326

Browse files
author
Tejas Shah
committed
Add AppAutomate ios sample tests
1 parent d1ab158 commit 4c6e326

File tree

9 files changed

+446
-0
lines changed

9 files changed

+446
-0
lines changed

ios/README.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
## Setup
2+
* Clone the repo
3+
* Install dependencies `mvn install`
4+
* Update *.conf.json files inside the `src/test/resources/conf` directory with your [BrowserStack Username and Access Key](https://www.browserstack.com/accounts/settings).
5+
6+
## Running your tests
7+
* To run a single test, run `mvn test -P single`
8+
* To run parallel tests, run `mvn test -P parallel`
9+
* To run local tests, run `mvn test -P local`
10+
11+
## Notes
12+
* You can view your test results on the [BrowserStack Automate dashboard](https://www.browserstack.com/automate)
13+
* Refer [Get Started](https://www.browserstack.com/app-automate/get-started#getting-started) document to configure the capabilities
14+
* You can export the environment variables for the Username and Access Key of your BrowserStack account.
15+
16+
```
17+
export BROWSERSTACK_USERNAME=<browserstack-username> &&
18+
export BROWSERSTACK_ACCESS_KEY=<browserstack-access-key>
19+
```
20+
21+
## Addtional Resources
22+
* [Getting Started with App Automate](https://www.browserstack.com/app-automate/get-started)

ios/pom.xml

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
2+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
3+
<modelVersion>4.0.0</modelVersion>
4+
5+
<groupId>com.browserstack</groupId>
6+
<artifactId>junit-browserstack</artifactId>
7+
<version>1.0-SNAPSHOT</version>
8+
<packaging>jar</packaging>
9+
10+
<name>junit-browserstack</name>
11+
<url>https://www.github.com/browserstack/junit-appium-app-browserstack</url>
12+
13+
<properties>
14+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
15+
<surefire.version>2.19.1</surefire.version>
16+
17+
<test.file></test.file>
18+
<config.file>default</config.file>
19+
</properties>
20+
21+
<dependencies>
22+
<dependency>
23+
<groupId>junit</groupId>
24+
<artifactId>junit</artifactId>
25+
<version>4.12</version>
26+
</dependency>
27+
<dependency>
28+
<groupId>commons-io</groupId>
29+
<artifactId>commons-io</artifactId>
30+
<version>1.3.2</version>
31+
</dependency>
32+
<dependency>
33+
<groupId>org.seleniumhq.selenium</groupId>
34+
<artifactId>selenium-java</artifactId>
35+
<version>2.52.0</version>
36+
</dependency>
37+
<dependency>
38+
<groupId>io.appium</groupId>
39+
<artifactId>java-client</artifactId>
40+
<version>4.1.2</version>
41+
</dependency>
42+
<dependency>
43+
<groupId>com.browserstack</groupId>
44+
<artifactId>browserstack-local-java</artifactId>
45+
<version>0.3.0</version>
46+
</dependency>
47+
<dependency>
48+
<groupId>com.googlecode.json-simple</groupId>
49+
<artifactId>json-simple</artifactId>
50+
<version>1.1.1</version>
51+
</dependency>
52+
</dependencies>
53+
54+
<build>
55+
<plugins>
56+
<plugin>
57+
<groupId>org.apache.maven.plugins</groupId>
58+
<artifactId>maven-surefire-plugin</artifactId>
59+
<version>2.12.4</version>
60+
</plugin>
61+
</plugins>
62+
</build>
63+
64+
<profiles>
65+
<profile>
66+
<id>single</id>
67+
<build>
68+
<plugins>
69+
<plugin>
70+
<groupId>org.apache.maven.plugins</groupId>
71+
<artifactId>maven-surefire-plugin</artifactId>
72+
<configuration>
73+
<includes>
74+
<include>com/browserstack/SingleTest.java</include>
75+
</includes>
76+
<systemPropertyVariables>
77+
<config>single.conf.json</config>
78+
</systemPropertyVariables>
79+
</configuration>
80+
</plugin>
81+
</plugins>
82+
</build>
83+
</profile>
84+
85+
<profile>
86+
<id>local</id>
87+
<build>
88+
<plugins>
89+
<plugin>
90+
<groupId>org.apache.maven.plugins</groupId>
91+
<artifactId>maven-surefire-plugin</artifactId>
92+
<configuration>
93+
<includes>
94+
<include>com/browserstack/LocalTest.java</include>
95+
</includes>
96+
<systemPropertyVariables>
97+
<config>local.conf.json</config>
98+
</systemPropertyVariables>
99+
</configuration>
100+
</plugin>
101+
</plugins>
102+
</build>
103+
</profile>
104+
105+
<profile>
106+
<id>parallel</id>
107+
<build>
108+
<plugins>
109+
<plugin>
110+
<groupId>org.apache.maven.plugins</groupId>
111+
<artifactId>maven-surefire-plugin</artifactId>
112+
<configuration>
113+
<includes>
114+
<include>com/browserstack/SingleTest.java</include>
115+
</includes>
116+
<systemPropertyVariables>
117+
<config>parallel.conf.json</config>
118+
</systemPropertyVariables>
119+
</configuration>
120+
</plugin>
121+
</plugins>
122+
</build>
123+
</profile>
124+
</profiles>
125+
126+
</project>
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
package com.browserstack;
2+
import com.browserstack.local.Local;
3+
4+
import java.net.URL;
5+
import java.util.Map;
6+
import java.util.List;
7+
import java.util.HashMap;
8+
import java.util.Iterator;
9+
import java.util.ArrayList;
10+
import java.io.FileReader;
11+
import org.json.simple.JSONObject;
12+
import org.json.simple.JSONArray;
13+
import org.json.simple.parser.JSONParser;
14+
15+
import org.openqa.selenium.remote.DesiredCapabilities;
16+
17+
import org.junit.After;
18+
import org.junit.Before;
19+
import org.junit.runner.RunWith;
20+
import org.junit.runners.Parameterized.Parameter;
21+
import org.junit.runners.Parameterized.Parameters;
22+
23+
import io.appium.java_client.ios.IOSDriver;
24+
import io.appium.java_client.ios.IOSElement;
25+
26+
27+
@RunWith(Parallelized.class)
28+
public class BrowserStackJUnitTest {
29+
public IOSDriver<IOSElement> driver;
30+
private Local l;
31+
32+
private static JSONObject config;
33+
34+
@Parameter(value = 0)
35+
public int taskID;
36+
37+
@Parameters
38+
public static Iterable<? extends Object> data() throws Exception {
39+
List<Integer> taskIDs = new ArrayList<Integer>();
40+
41+
if(System.getProperty("config") != null) {
42+
JSONParser parser = new JSONParser();
43+
config = (JSONObject) parser.parse(new FileReader("src/test/resources/conf/" + System.getProperty("config")));
44+
int envs = ((JSONArray)config.get("environments")).size();
45+
46+
for(int i=0; i<envs; i++) {
47+
taskIDs.add(i);
48+
}
49+
}
50+
51+
return taskIDs;
52+
}
53+
54+
@Before
55+
public void setUp() throws Exception {
56+
JSONArray envs = (JSONArray) config.get("environments");
57+
58+
DesiredCapabilities capabilities = new DesiredCapabilities();
59+
60+
Map<String, String> envCapabilities = (Map<String, String>) envs.get(taskID);
61+
Iterator it = envCapabilities.entrySet().iterator();
62+
while (it.hasNext()) {
63+
Map.Entry pair = (Map.Entry)it.next();
64+
capabilities.setCapability(pair.getKey().toString(), pair.getValue().toString());
65+
}
66+
67+
Map<String, String> commonCapabilities = (Map<String, String>) config.get("capabilities");
68+
it = commonCapabilities.entrySet().iterator();
69+
while (it.hasNext()) {
70+
Map.Entry pair = (Map.Entry)it.next();
71+
if(capabilities.getCapability(pair.getKey().toString()) == null){
72+
capabilities.setCapability(pair.getKey().toString(), pair.getValue().toString());
73+
}
74+
}
75+
76+
String username = System.getenv("BROWSERSTACK_USERNAME");
77+
if(username == null) {
78+
username = (String) config.get("user");
79+
}
80+
81+
String accessKey = System.getenv("BROWSERSTACK_ACCESS_KEY");
82+
if(accessKey == null) {
83+
accessKey = (String) config.get("key");
84+
}
85+
86+
if(capabilities.getCapability("browserstack.local") != null && capabilities.getCapability("browserstack.local") == "true"){
87+
l = new Local();
88+
Map<String, String> options = new HashMap<String, String>();
89+
options.put("key", accessKey);
90+
l.start(options);
91+
}
92+
93+
driver = new IOSDriver<IOSElement>(new URL("http://"+username+":"+accessKey+"@"+config.get("server")+"/wd/hub"), capabilities);
94+
}
95+
96+
@After
97+
public void tearDown() throws Exception {
98+
driver.quit();
99+
if(l != null) l.stop();
100+
}
101+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package com.browserstack;
2+
3+
import static org.junit.Assert.*;
4+
5+
import java.io.File;
6+
import org.junit.Test;
7+
import org.apache.commons.io.FileUtils;
8+
9+
import org.openqa.selenium.WebDriver;
10+
import org.openqa.selenium.OutputType;
11+
import org.openqa.selenium.TakesScreenshot;
12+
import org.openqa.selenium.support.ui.WebDriverWait;
13+
import org.openqa.selenium.support.ui.ExpectedCondition;
14+
import org.openqa.selenium.support.ui.ExpectedConditions;
15+
16+
import io.appium.java_client.MobileBy;
17+
import io.appium.java_client.ios.IOSElement;
18+
19+
20+
public class LocalTest extends BrowserStackJUnitTest {
21+
22+
@Test
23+
public void test() throws Exception {
24+
IOSElement testButton = (IOSElement) new WebDriverWait(driver, 30).until(
25+
ExpectedConditions.elementToBeClickable(MobileBy.AccessibilityId("TestBrowserStackLocal")));
26+
testButton.click();
27+
28+
WebDriverWait wait = new WebDriverWait(driver, 30);
29+
wait.until(new ExpectedCondition<Boolean>() {
30+
@Override
31+
public Boolean apply(WebDriver d) {
32+
String result = d.findElement(MobileBy.AccessibilityId("ResultBrowserStackLocal")).getAttribute("value");
33+
return result != null && result.length() > 0;
34+
}
35+
});
36+
IOSElement resultElement = (IOSElement) driver.findElement(MobileBy.AccessibilityId("ResultBrowserStackLocal"));
37+
38+
String resultString = resultElement.getText().toLowerCase();
39+
System.out.println(resultString);
40+
if(resultString.contains("not working")) {
41+
File scrFile = (File) ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
42+
FileUtils.copyFile(scrFile, new File(System.getProperty("user.dir") + "/screenshot.png"));
43+
System.out.println("Screenshot stored at " + System.getProperty("user.dir") + "/screenshot.png");
44+
throw new Error("Unexpected BrowserStackLocal test result");
45+
}
46+
47+
String expectedString = "Up and running";
48+
assertTrue(resultString.contains(expectedString.toLowerCase()));
49+
}
50+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package com.browserstack;
2+
3+
import java.util.concurrent.ExecutorService;
4+
import java.util.concurrent.Executors;
5+
import java.util.concurrent.TimeUnit;
6+
7+
import org.junit.runners.Parameterized;
8+
import org.junit.runners.model.RunnerScheduler;
9+
10+
public class Parallelized extends Parameterized {
11+
12+
private static class ThreadPoolScheduler implements RunnerScheduler {
13+
private ExecutorService executor;
14+
15+
public ThreadPoolScheduler() {
16+
String threads = System.getProperty("junit.parallel.threads", "8");
17+
int numThreads = Integer.parseInt(threads);
18+
executor = Executors.newFixedThreadPool(numThreads);
19+
}
20+
21+
@Override
22+
public void finished() {
23+
executor.shutdown();
24+
try {
25+
executor.awaitTermination(10, TimeUnit.MINUTES);
26+
} catch (InterruptedException exc) {
27+
throw new RuntimeException(exc);
28+
}
29+
}
30+
31+
@Override
32+
public void schedule(Runnable childStatement) {
33+
executor.submit(childStatement);
34+
}
35+
}
36+
37+
public Parallelized(Class klass) throws Throwable {
38+
super(klass);
39+
setScheduler(new ThreadPoolScheduler());
40+
}
41+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package com.browserstack;
2+
3+
import static org.junit.Assert.*;
4+
5+
import org.junit.Test;
6+
import java.util.List;
7+
8+
import io.appium.java_client.MobileBy;
9+
import io.appium.java_client.ios.IOSElement;
10+
11+
import org.openqa.selenium.support.ui.WebDriverWait;
12+
import org.openqa.selenium.support.ui.ExpectedConditions;
13+
14+
15+
public class SingleTest extends BrowserStackJUnitTest {
16+
17+
@Test
18+
public void test() throws Exception {
19+
IOSElement loginButton = (IOSElement) new WebDriverWait(driver, 30).until(
20+
ExpectedConditions.elementToBeClickable(MobileBy.AccessibilityId("Log In")));
21+
loginButton.click();
22+
IOSElement emailTextField = (IOSElement) new WebDriverWait(driver, 30).until(
23+
ExpectedConditions.elementToBeClickable(MobileBy.AccessibilityId("Email address")));
24+
25+
// element.sendKeys() method is not supported in Appium 1.6.3
26+
// Workaround for sendKeys() method:
27+
emailTextField.click();
28+
String email = "[email protected]";
29+
for (int i = 0; i < email.length(); i++) {
30+
driver.findElementByXPath("//XCUIElementTypeKey[@name='" + email.charAt(i) + "']").click();
31+
}
32+
33+
driver.findElementByAccessibilityId("Next").click();
34+
Thread.sleep(5000);
35+
36+
List<IOSElement> textElements = driver.findElementsByXPath("//XCUIElementTypeStaticText");
37+
assertTrue(textElements.size() > 0);
38+
String matchedString = "";
39+
for(IOSElement textElement : textElements) {
40+
String textContent = textElement.getText();
41+
if(textContent.contains("not registered")) {
42+
matchedString = textContent;
43+
}
44+
}
45+
46+
System.out.println(matchedString);
47+
assertTrue(matchedString.contains("not registered on WordPress.com"));
48+
}
49+
}

0 commit comments

Comments
 (0)