java appium tests and jenkins test
This commit is contained in:
parent
58f8eecffa
commit
7e7920358f
|
@ -1,5 +1,12 @@
|
||||||
node {
|
node {
|
||||||
|
def apkUrl = ''
|
||||||
|
def ipaUrl = ''
|
||||||
|
def testPassed = true
|
||||||
|
|
||||||
sh 'source /etc/profile'
|
sh 'source /etc/profile'
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
stage('Git & Dependencies') {
|
stage('Git & Dependencies') {
|
||||||
git([url: 'https://github.com/status-im/status-react.git', branch: env.BRANCH_NAME])
|
git([url: 'https://github.com/status-im/status-react.git', branch: env.BRANCH_NAME])
|
||||||
// Checkout master because used for iOS Plist version information
|
// Checkout master because used for iOS Plist version information
|
||||||
|
@ -15,13 +22,11 @@ node {
|
||||||
stage('Build') {
|
stage('Build') {
|
||||||
sh 'lein prod-build'
|
sh 'lein prod-build'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Android
|
||||||
stage('Build (Android)') {
|
stage('Build (Android)') {
|
||||||
sh 'cd android && ./gradlew assembleRelease'
|
sh 'cd android && ./gradlew assembleRelease'
|
||||||
}
|
}
|
||||||
stage('Build (iOS)') {
|
|
||||||
sh 'export RCT_NO_LAUNCH_PACKAGER=true && xcodebuild -workspace ios/StatusIm.xcworkspace -scheme StatusIm -configuration release -archivePath status clean archive'
|
|
||||||
sh 'xcodebuild -exportArchive -exportPath status -archivePath status.xcarchive -exportOptionsPlist /Users/Xcloud/archive.plist'
|
|
||||||
}
|
|
||||||
stage('Deploy (Android)') {
|
stage('Deploy (Android)') {
|
||||||
def artifact_dir = pwd() + '/android/app/build/outputs/apk/'
|
def artifact_dir = pwd() + '/android/app/build/outputs/apk/'
|
||||||
def artifact = new File(artifact_dir + 'app-release.apk')
|
def artifact = new File(artifact_dir + 'app-release.apk')
|
||||||
|
@ -32,14 +37,42 @@ node {
|
||||||
artifact.renameTo artifact_dir + filename
|
artifact.renameTo artifact_dir + filename
|
||||||
def uploadSpec = '{ "files": [ { "pattern": "*apk/' + filename + '", "target": "pull-requests" }]}'
|
def uploadSpec = '{ "files": [ { "pattern": "*apk/' + filename + '", "target": "pull-requests" }]}'
|
||||||
def buildInfo = server.upload(uploadSpec)
|
def buildInfo = server.upload(uploadSpec)
|
||||||
slackSend color: 'good', message: env.BRANCH_NAME + ' (Android) http://artifacts.status.im:8081/artifactory/pull-requests/' + filename
|
apkUrl = 'http://artifacts.status.im:8081/artifactory/pull-requests/' + filename
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
stage('Test (Android)') {
|
||||||
|
sauce('b9aded57-5cc1-4f6b-b5ea-42d989987852') {
|
||||||
|
sh 'cd test/appium && mvn -DapkUrl=' + apkUrl + ' test'
|
||||||
|
saucePublisher()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch(e) {
|
||||||
|
testPassed = false
|
||||||
|
}
|
||||||
|
|
||||||
|
// iOS
|
||||||
|
stage('Build (iOS)') {
|
||||||
|
sh 'export RCT_NO_LAUNCH_PACKAGER=true && xcodebuild -workspace ios/StatusIm.xcworkspace -scheme StatusIm -configuration release -archivePath status clean archive'
|
||||||
|
sh 'xcodebuild -exportArchive -exportPath status -archivePath status.xcarchive -exportOptionsPlist /Users/Xcloud/archive.plist'
|
||||||
}
|
}
|
||||||
stage('Deploy (iOS)') {
|
stage('Deploy (iOS)') {
|
||||||
withCredentials([string(credentialsId: 'diawi-token', variable: 'token')]) {
|
withCredentials([string(credentialsId: 'diawi-token', variable: 'token')]) {
|
||||||
def job = sh(returnStdout: true, script: 'curl https://upload.diawi.com/ -F token='+token+' -F file=@status/StatusIm.ipa -F find_by_udid=0 -F wall_of_apps=0 | jq -r ".job"').trim()
|
def job = sh(returnStdout: true, script: 'curl https://upload.diawi.com/ -F token='+token+' -F file=@status/StatusIm.ipa -F find_by_udid=0 -F wall_of_apps=0 | jq -r ".job"').trim()
|
||||||
sh 'sleep 10'
|
sh 'sleep 10'
|
||||||
def hash = sh(returnStdout: true, script: "curl -vvv 'https://upload.diawi.com/status?token="+token+"&job="+job+"'|jq -r '.hash'").trim()
|
def hash = sh(returnStdout: true, script: "curl -vvv 'https://upload.diawi.com/status?token="+token+"&job="+job+"'|jq -r '.hash'").trim()
|
||||||
slackSend color: 'good', message: env.BRANCH_NAME + ' (iOS) https://i.diawi.com/' + hash
|
ipaUrl = 'https://i.diawi.com/' + hash
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} catch (e) {
|
||||||
|
slackSend color: 'bad', message: env.BRANCH_NAME + ' failed to build. ' + env.BUILD_URL
|
||||||
|
throw e
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('Slack Notification') {
|
||||||
|
def c = (testPassed ? 'good' : 'warning' )
|
||||||
|
slackSend color: c, message: env.BRANCH_NAME + ' (Android, test: ' + (testPassed ? ':+1:' : ':-1:') + ') ' + apkUrl
|
||||||
|
slackSend color: c, message: env.BRANCH_NAME + ' (iOS) ' + ipaUrl
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
![Status - A Browser, Messenger, and gateway to the decentralised world of Ethereum](https://status.im/img/status-github-banner@2x.png?v=1.1 "Status - A Browser, Messenger, and gateway to the decentralised world of Ethereum")
|
![Status - A Browser, Messenger, and gateway to the decentralised world of Ethereum](https://status.im/img/status-github-banner@2x.png?v=1.1 "Status - A Browser, Messenger, and gateway to the decentralised world of Ethereum")
|
||||||
// TODO badges
|
[![Build Status](https://saucelabs.com/buildstatus/jarrad-status)](https://saucelabs.com/beta/builds/50ccf11ec1a44d88b6eb989929e5789f)
|
||||||
|
|
||||||
# Status - a Mobile Ethereum Operating System
|
# Status - a Mobile Ethereum Operating System
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,78 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
|
||||||
|
<output url="file://$MODULE_DIR$/target/classes" />
|
||||||
|
<output-test url="file://$MODULE_DIR$/target/test-classes" />
|
||||||
|
<content url="file://$MODULE_DIR$">
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/target" />
|
||||||
|
</content>
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
<orderEntry type="library" name="Maven: io.appium:java-client:5.0.0-BETA7" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.google.code.gson:gson:2.8.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.apache.httpcomponents:httpclient:4.5.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.apache.httpcomponents:httpcore:4.4.4" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: commons-logging:commons-logging:1.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: commons-codec:commons-codec:1.9" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: cglib:cglib:3.2.4" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.ow2.asm:asm:5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.apache.ant:ant:1.9.6" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.apache.ant:ant-launcher:1.9.6" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: commons-validator:commons-validator:1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: commons-beanutils:commons-beanutils:1.9.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: commons-digester:commons-digester:1.8.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: commons-collections:commons-collections:3.2.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.apache.commons:commons-lang3:3.5" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: commons-io:commons-io:2.5" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework:spring-context:4.3.5.RELEASE" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework:spring-aop:4.3.5.RELEASE" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework:spring-beans:4.3.5.RELEASE" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework:spring-core:4.3.5.RELEASE" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework:spring-expression:4.3.5.RELEASE" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.aspectj:aspectjweaver:1.8.10" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.openpnp:opencv:3.2.0-1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.seleniumhq.selenium:selenium-java:3.3.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.seleniumhq.selenium:selenium-chrome-driver:3.3.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.seleniumhq.selenium:selenium-remote-driver:3.3.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.seleniumhq.selenium:selenium-api:3.3.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: cglib:cglib-nodep:3.2.4" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.apache.commons:commons-exec:1.3" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.google.guava:guava:21.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: net.java.dev.jna:jna-platform:4.1.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: net.java.dev.jna:jna:4.1.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.seleniumhq.selenium:selenium-edge-driver:3.3.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.seleniumhq.selenium:selenium-firefox-driver:3.3.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.seleniumhq.selenium:selenium-ie-driver:3.3.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.seleniumhq.selenium:selenium-opera-driver:3.3.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.seleniumhq.selenium:selenium-safari-driver:3.3.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.codeborne:phantomjsdriver:1.4.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.seleniumhq.selenium:htmlunit-driver:2.24" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.seleniumhq.selenium:selenium-support:3.3.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.hamcrest:hamcrest-library:1.3" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: net.sourceforge.htmlunit:htmlunit:2.24" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: xalan:xalan:2.7.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: xalan:serializer:2.7.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.apache.httpcomponents:httpmime:4.5.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: net.sourceforge.htmlunit:htmlunit-core-js:2.23" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: net.sourceforge.htmlunit:neko-htmlunit:2.24" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: xerces:xercesImpl:2.11.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: xml-apis:xml-apis:1.4.01" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: net.sourceforge.cssparser:cssparser:0.9.21" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.w3c.css:sac:1.3" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.eclipse.jetty.websocket:websocket-client:9.2.20.v20161216" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-util:9.2.20.v20161216" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-io:9.2.20.v20161216" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.eclipse.jetty.websocket:websocket-common:9.2.20.v20161216" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.eclipse.jetty.websocket:websocket-api:9.2.20.v20161216" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: junit:junit:4.12" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.hamcrest:hamcrest-core:1.3" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.saucelabs:sauce_junit:2.1.23" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.saucelabs:sauce_java_common:2.1.23" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.saucelabs:saucerest:1.0.32" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.googlecode.json-simple:json-simple:1.1.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.json:json:20090211" level="project" />
|
||||||
|
</component>
|
||||||
|
</module>
|
|
@ -0,0 +1,56 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<groupId>im.status</groupId>
|
||||||
|
<artifactId>AppiumTests</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.appium</groupId>
|
||||||
|
<artifactId>java-client</artifactId>
|
||||||
|
<version>5.0.0-BETA7</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.seleniumhq.selenium</groupId>
|
||||||
|
<artifactId>selenium-java</artifactId>
|
||||||
|
<version>3.3.1</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<version>4.12</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.saucelabs</groupId>
|
||||||
|
<artifactId>sauce_junit</artifactId>
|
||||||
|
<version>2.1.23</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
</dependencies>
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>3.6.1</version>
|
||||||
|
<configuration>
|
||||||
|
<source>1.8</source>
|
||||||
|
<target>1.8</target>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
<version>2.20</version>
|
||||||
|
<configuration>
|
||||||
|
<parallel>methods</parallel>
|
||||||
|
<threadCount>4</threadCount>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
|
@ -0,0 +1,17 @@
|
||||||
|
package app;
|
||||||
|
|
||||||
|
import io.appium.java_client.AppiumDriver;
|
||||||
|
import screens.ChatScreen;
|
||||||
|
|
||||||
|
|
||||||
|
public class StatusApp {
|
||||||
|
|
||||||
|
private final AppiumDriver driver;
|
||||||
|
|
||||||
|
public StatusApp(AppiumDriver driver) {
|
||||||
|
this.driver = driver;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ChatScreen ChatScreen() { return new ChatScreen(driver); }
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
package screens;
|
||||||
|
|
||||||
|
import io.appium.java_client.AppiumDriver;
|
||||||
|
import io.appium.java_client.MobileElement;
|
||||||
|
import io.appium.java_client.pagefactory.AppiumFieldDecorator;
|
||||||
|
import org.openqa.selenium.By;
|
||||||
|
import org.openqa.selenium.OutputType;
|
||||||
|
import org.openqa.selenium.WebElement;
|
||||||
|
import org.openqa.selenium.support.PageFactory;
|
||||||
|
import org.openqa.selenium.support.ui.ExpectedConditions;
|
||||||
|
import org.openqa.selenium.support.ui.WebDriverWait;
|
||||||
|
|
||||||
|
public class AbstractScreen {
|
||||||
|
|
||||||
|
protected final AppiumDriver<WebElement> driver;
|
||||||
|
protected WebDriverWait wait;
|
||||||
|
|
||||||
|
|
||||||
|
public AbstractScreen(AppiumDriver<WebElement> driver) {
|
||||||
|
this.driver = driver;
|
||||||
|
wait = new WebDriverWait(driver,45);
|
||||||
|
PageFactory.initElements(new AppiumFieldDecorator(driver), this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public MobileElement findElementWithTimeout(By by, int timeOutInSeconds) {
|
||||||
|
return (MobileElement)(new WebDriverWait(driver, timeOutInSeconds)).until(ExpectedConditions.presenceOfElementLocated(by));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void takeScreenShot(){
|
||||||
|
driver.getScreenshotAs(OutputType.BASE64);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,75 @@
|
||||||
|
package screens;
|
||||||
|
|
||||||
|
import io.appium.java_client.AppiumDriver;
|
||||||
|
import io.appium.java_client.pagefactory.AndroidFindBy;
|
||||||
|
import org.openqa.selenium.By;
|
||||||
|
import org.openqa.selenium.InvalidSelectorException;
|
||||||
|
import org.openqa.selenium.WebElement;
|
||||||
|
import org.openqa.selenium.support.ui.ExpectedConditions;
|
||||||
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
|
|
||||||
|
public class ChatScreen extends AbstractScreen {
|
||||||
|
|
||||||
|
public ChatScreen(AppiumDriver<WebElement> driver){
|
||||||
|
super(driver);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@AndroidFindBy(id="android:id/button1")
|
||||||
|
public WebElement btnContinue;
|
||||||
|
|
||||||
|
@AndroidFindBy(accessibility="request-password")
|
||||||
|
public WebElement requestPassword;
|
||||||
|
|
||||||
|
@AndroidFindBy(accessibility="chat-message-input")
|
||||||
|
public WebElement inputChatMessage;
|
||||||
|
|
||||||
|
@AndroidFindBy(accessibility="chat-send-button")
|
||||||
|
public WebElement btnSend;
|
||||||
|
|
||||||
|
@AndroidFindBy(accessibility="request-phone")
|
||||||
|
public WebElement btnRequestPhone;
|
||||||
|
|
||||||
|
@AndroidFindBy(accessibility="chat-cancel-response-button")
|
||||||
|
public WebElement btnCancelPasswordRequest;
|
||||||
|
|
||||||
|
public void continueForRootedDevice()
|
||||||
|
{
|
||||||
|
if (isElementPresent(By.id("android:id/button1"))) {
|
||||||
|
btnContinue.click();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void createPassword(String password){
|
||||||
|
requestPassword.click();
|
||||||
|
for (int i=0; i<2; i++){
|
||||||
|
inputChatMessage.sendKeys(password);
|
||||||
|
btnSend.click();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void verifyPasswordIsSet(){
|
||||||
|
//button "tap to enter phone number" is shown
|
||||||
|
wait.until(ExpectedConditions.elementToBeClickable(btnRequestPhone));
|
||||||
|
|
||||||
|
//screen contains text "Phew that was hard" TODO: replace hardcoded string "Find a bug" check
|
||||||
|
Assert.isTrue(driver.getPageSource().contains("Find a bug"),"Text Phew that was hard is not found on screen");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void verifyPasswordRequestIsVisible(){
|
||||||
|
//button "tap to enter phone number" is shown
|
||||||
|
wait.until(ExpectedConditions.elementToBeClickable(requestPassword));
|
||||||
|
//screen contains text "Phew that was hard" TODO: replace hardcoded string "Welcome to Status " check
|
||||||
|
Assert.isTrue(driver.getPageSource().contains("Welcome to Status"),"Welcome to Status is not found on screen");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public boolean isElementPresent(By locator) {
|
||||||
|
try {
|
||||||
|
return driver.findElements(locator).size() > 0;
|
||||||
|
} catch (InvalidSelectorException ex) {
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,62 @@
|
||||||
|
package tests;
|
||||||
|
|
||||||
|
import app.StatusApp;
|
||||||
|
import com.saucelabs.common.SauceOnDemandSessionIdProvider;
|
||||||
|
import io.appium.java_client.android.AndroidDriver;
|
||||||
|
import org.junit.*;
|
||||||
|
import org.junit.rules.TestName;
|
||||||
|
import org.openqa.selenium.WebElement;
|
||||||
|
import org.openqa.selenium.remote.RemoteWebDriver;
|
||||||
|
import utility.AppiumDriverBuilder;
|
||||||
|
import java.net.MalformedURLException;
|
||||||
|
import java.net.URL;
|
||||||
|
import com.saucelabs.junit.SauceOnDemandTestWatcher;
|
||||||
|
import com.saucelabs.common.SauceOnDemandAuthentication;
|
||||||
|
|
||||||
|
public abstract class AbstractTest implements SauceOnDemandSessionIdProvider {
|
||||||
|
|
||||||
|
private AndroidDriver<WebElement> driver;
|
||||||
|
protected StatusApp app;
|
||||||
|
|
||||||
|
public static final String USERNAME = System.getenv("SAUCE_USERNAME");
|
||||||
|
public static final String ACCESS_KEY = System.getenv("SAUCE_ACCESS_KEY");
|
||||||
|
public static final String URL = "https://" + USERNAME + ":" + ACCESS_KEY + "@ondemand.saucelabs.com:443/wd/hub";
|
||||||
|
// public String buildTag = System.getenv("JOB_NAME") + "__" + System.getenv("BUILD_NUMBER");
|
||||||
|
|
||||||
|
protected String sessionId;
|
||||||
|
|
||||||
|
public SauceOnDemandAuthentication authentication = new SauceOnDemandAuthentication(USERNAME, ACCESS_KEY);
|
||||||
|
|
||||||
|
@Rule
|
||||||
|
public SauceOnDemandTestWatcher resultReportingTestWatcher = new SauceOnDemandTestWatcher(this, authentication);
|
||||||
|
|
||||||
|
@Rule
|
||||||
|
public TestName name = new TestName() {
|
||||||
|
public String getMethodName() {
|
||||||
|
return String.format("%s", super.getMethodName());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void SetupRemote() throws MalformedURLException {
|
||||||
|
driver = AppiumDriverBuilder.forAndroid()
|
||||||
|
.withEndpoint(new URL(URL))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
app = new StatusApp(driver);
|
||||||
|
this.sessionId = (((RemoteWebDriver) driver).getSessionId()).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void teardown(){
|
||||||
|
//close the app
|
||||||
|
driver.quit();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getSessionId() {
|
||||||
|
return sessionId;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
package tests;
|
||||||
|
|
||||||
|
|
||||||
|
import org.junit.*;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public class InitialRunTest extends AbstractTest {
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void canRunAppTest()
|
||||||
|
{
|
||||||
|
app.ChatScreen().continueForRootedDevice();
|
||||||
|
app.ChatScreen().verifyPasswordRequestIsVisible();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void canCreatePasswordTest()
|
||||||
|
{
|
||||||
|
|
||||||
|
app.ChatScreen().continueForRootedDevice();
|
||||||
|
app.ChatScreen().createPassword("password");
|
||||||
|
app.ChatScreen().verifyPasswordIsSet();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,58 @@
|
||||||
|
package utility;
|
||||||
|
|
||||||
|
|
||||||
|
import io.appium.java_client.AppiumDriver;
|
||||||
|
import io.appium.java_client.android.AndroidDriver;
|
||||||
|
import org.openqa.selenium.WebElement;
|
||||||
|
import org.openqa.selenium.remote.DesiredCapabilities;
|
||||||
|
|
||||||
|
|
||||||
|
import java.net.MalformedURLException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.sql.Timestamp;
|
||||||
|
|
||||||
|
|
||||||
|
public abstract class AppiumDriverBuilder<SELF, DRIVER extends AppiumDriver> {
|
||||||
|
|
||||||
|
public String jobName = System.getenv("JOB_NAME");
|
||||||
|
public String buildNumber = System.getenv("BUILD_NUMBER");
|
||||||
|
protected URL endpoint;
|
||||||
|
DesiredCapabilities capabilities = new DesiredCapabilities();
|
||||||
|
|
||||||
|
public static AndroidDriverBuilder forAndroid() throws MalformedURLException {
|
||||||
|
return new AndroidDriverBuilder();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class AndroidDriverBuilder extends AppiumDriverBuilder<AndroidDriverBuilder, AndroidDriver> {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public AndroidDriver build() {
|
||||||
|
capabilities.setCapability("appiumVersion", "1.6.3");
|
||||||
|
capabilities.setCapability("deviceName","Samsung Galaxy S4 Emulator");
|
||||||
|
capabilities.setCapability("deviceOrientation", "portrait");
|
||||||
|
capabilities.setCapability("browserName", "");
|
||||||
|
capabilities.setCapability("platformVersion","4.4");
|
||||||
|
capabilities.setCapability("platformName","Android");
|
||||||
|
|
||||||
|
jobName = (null == jobName) ? "Local run " : jobName;
|
||||||
|
buildNumber = (null == buildNumber) ? new Timestamp(System.currentTimeMillis()).toString() : buildNumber;
|
||||||
|
capabilities.setCapability("build", jobName + "__" + buildNumber);
|
||||||
|
|
||||||
|
//read url to apk file from Jenkins property or from maven parameter
|
||||||
|
// example of maven run: mvn -DapkUrl=http://artifacts.status.im:8081/artifactory/nightlies-local/im.status.ethereum-baebbe.apk test
|
||||||
|
capabilities.setCapability("app", System.getProperty("apkUrl"));
|
||||||
|
return new AndroidDriver<WebElement>(endpoint, capabilities);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public SELF withEndpoint(URL endpoint) {
|
||||||
|
this.endpoint = endpoint;
|
||||||
|
|
||||||
|
return (SELF) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract DRIVER build();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue