Skip to content
Permalink
Browse files

Release 1.5 (#26)

* Release 1.5

* Add support for AWS Devicefarm
* Implement app package upload for Browserstack
* Introduce PropertiesHolder
* Update Carousell scenarios
* Minor fixes and refactorings
* Remove pCloudy PoC
* Update libraries
* Support Cucumber tag expressions
* Add unit tests
  • Loading branch information...
martinschneider committed May 7, 2019
1 parent f4ee0d0 commit 371fb1baaacf4ac4c8b2dd2b9b481fb334cc92a3
Showing with 2,137 additions and 410 deletions.
  1. +2 −3 .travis.yml
  2. +12 −6 {justtestlah-pcloudy → justtestlah-awsdevicefarm}/pom.xml
  3. +183 −0 ...h-awsdevicefarm/src/main/java/io/github/martinschneider/justtestlah/awsdevicefarm/AWSService.java
  4. +212 −0 ...wsdevicefarm/src/main/java/io/github/martinschneider/justtestlah/awsdevicefarm/AWSTestRunner.java
  5. +105 −0 ...cefarm/src/main/java/io/github/martinschneider/justtestlah/awsdevicefarm/DeviceFilterFactory.java
  6. +63 −0 ...m/src/main/java/io/github/martinschneider/justtestlah/awsdevicefarm/TestConfigurationFactory.java
  7. +36 −0 ...awsdevicefarm/src/main/java/io/github/martinschneider/justtestlah/awsdevicefarm/TestPackager.java
  8. +86 −0 ...devicefarm/src/main/java/io/github/martinschneider/justtestlah/awsdevicefarm/TestSpecFactory.java
  9. +27 −0 .../java/io/github/martinschneider/justtestlah/awsdevicefarm/devicefilter/DeviceFilterConstants.java
  10. +49 −0 ...ava/io/github/martinschneider/justtestlah/awsdevicefarm/devicefilter/DeviceFilterStringUtils.java
  11. +26 −0 ...farm/src/main/java/io/github/martinschneider/justtestlah/awsdevicefarm/utils/FormattingUtils.java
  12. +6 −1 justtestlah-browserstack/pom.xml
  13. +93 −3 ...c/main/java/io/github/martinschneider/justtestlah/configuration/BrowserStackWebDriverBuilder.java
  14. +6 −1 justtestlah-core/pom.xml
  15. +3 −4 justtestlah-core/src/main/java/io/github/martinschneider/justtestlah/base/BasePage.java
  16. +21 −17 ...core/src/main/java/io/github/martinschneider/justtestlah/configuration/LocalWebDriverBuilder.java
  17. +74 −0 ...tlah-core/src/main/java/io/github/martinschneider/justtestlah/configuration/PropertiesHolder.java
  18. +2 −12 ...testlah-core/src/main/java/io/github/martinschneider/justtestlah/configuration/SpringContext.java
  19. +142 −121 justtestlah-core/src/main/java/io/github/martinschneider/justtestlah/junit/JustTestLahRunner.java
  20. +7 −2 justtestlah-core/src/main/java/io/github/martinschneider/justtestlah/locator/LocatorMap.java
  21. +15 −7 ...tlah-core/src/main/java/io/github/martinschneider/justtestlah/log/LogApplicationInfoEnricher.java
  22. +2 −1 justtestlah-core/src/main/java/io/github/martinschneider/justtestlah/steps/WebDriverHooks.java
  23. +18 −5 justtestlah-core/src/main/java/io/github/martinschneider/justtestlah/user/UserService.java
  24. +40 −0 justtestlah-core/src/main/java/io/github/martinschneider/justtestlah/utils/FileEntity.java
  25. +52 −0 justtestlah-core/src/main/java/io/github/martinschneider/justtestlah/utils/OutputStreamProgress.java
  26. +1 −1 justtestlah-core/src/main/java/io/github/martinschneider/justtestlah/visual/ImageUtils.java
  27. +41 −5 ...testlah-core/src/test/java/io/github/martinschneider/justtestlah/junit/JustTestLahRunnerTest.java
  28. +51 −0 ...-core/src/test/java/io/github/martinschneider/justtestlah/log/LogApplicationInfoEnricherTest.java
  29. +18 −0 justtestlah-core/src/test/java/io/github/martinschneider/justtestlah/visual/TemplateMatcherTest.java
  30. +1 −1 justtestlah-core/src/test/resources/features/stackoverflow/NewQuestion.feature
  31. +6 −0 ...e/src/test/resources/io/github/martinschneider/justtestlah/junit/justtestlah_injection.properties
  32. +2 −1 ...github/martinschneider/justtestlah/junit/{justtestlah.properties → justtestlah_legacy.properties}
  33. +6 −0 ...c/test/resources/io/github/martinschneider/justtestlah/junit/justtestlah_tagexpression.properties
  34. +2 −0 justtestlah-core/src/test/resources/justtestlah.properties
  35. +61 −0 justtestlah-demos/demos/carousell_aws.properties
  36. +35 −0 justtestlah-demos/demos/carousell_browserstack.properties
  37. +18 −0 justtestlah-demos/demos/carousell_local.properties
  38. +62 −0 justtestlah-demos/demos/stackoverflow_aws.properties
  39. +35 −0 justtestlah-demos/demos/stackoverflow_browserstack.properties
  40. +16 −0 justtestlah-demos/demos/stackoverflow_local.properties
  41. +77 −8 justtestlah-demos/pom.xml
  42. +23 −0 justtestlah-demos/src/main/assembly/aws-devicefarm.xml
  43. +20 −0 justtestlah-demos/src/main/resources/logback-aws.xml
  44. +1 −1 ...-demos/src/test/java/io/github/martinschneider/justtestlah/examples/carousell/pages/HomePage.java
  45. +2 −2 ...demos/src/test/java/io/github/martinschneider/justtestlah/examples/carousell/pages/LoginPage.java
  46. +100 −0 justtestlah-demos/src/test/resources/aws-devicefarm-testspec-template.yml
  47. +1 −1 justtestlah-demos/src/test/resources/features/stackoverflow/NewQuestion.feature
  48. +1 −1 justtestlah-demos/src/test/resources/features/stackoverflow/Search.feature
  49. +11 −3 ...s/src/test/resources/io/github/martinschneider/justtestlah/examples/carousell/pages/HomePage.yaml
  50. +5 −5 .../src/test/resources/io/github/martinschneider/justtestlah/examples/carousell/pages/LoginPage.yaml
  51. +72 −10 justtestlah-demos/src/test/resources/justtestlah.properties
  52. 0 ...st/resources/{io/github/martinschneider/justtestlah/user/users.properties → testusers.properties}
  53. +1 −1 justtestlah-mobile-tools/pom.xml
  54. +4 −1 ...ools/src/main/java/io/github/martinschneider/justtestlah/mobile/tools/ApplicationInfoService.java
  55. +0 −11 justtestlah-pcloudy/README.md
  56. BIN justtestlah-pcloudy/pCloudy-java-connector-11.0.5-jar-with-dependencies.jar
  57. +0 −136 ...dy/src/main/java/io/github/martinschneider/justtestlah/configuration/PCloudyWebDriverBuilder.java
  58. +0 −2 ...stlah-pcloudy/src/main/java/io/github/martinschneider/justtestlah/configuration/package-info.java
  59. +31 −22 pom.xml
  60. +151 −15 src/site/markdown/index.md
@@ -2,13 +2,12 @@ language: java
os:
- linux
jdk:
- openjdk8
- openjdk9
- openjdk10
- openjdk11
- openjdk12
cache:
directories: $HOME/.m2
install: mvn install:install-file -Dfile=justtestlah-pcloudy/pCloudy-java-connector-11.0.5-jar-with-dependencies.jar -DgroupId=pCloudy-java-connector -DartifactId=pCloudy-java-connector -Dversion=11.0.5 -Dpackaging=jar
install:
addons:
homebrew:
packages: scrcpy
@@ -3,24 +3,30 @@
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>
<artifactId>justtestlah-pcloudy</artifactId>
<name>JustTestLah! PCloudy</name>
<artifactId>justtestlah-awsdevicefarm</artifactId>
<name>JustTestLah! AWS Devicefarm</name>
<description>JustTestLah! is a JAVA test framework targeting projects that support multiple platforms, in particular Web, Android and iOS. It follows a BDD approach and allows testing against all platforms using the same feature files. JustTestLah's main aim is to make the configuration and the actual test code as easy as possible.</description>
<parent>
<groupId>io.github.martinschneider</groupId>
<artifactId>justtestlah-parent</artifactId>
<version>1.4</version>
<version>1.5-SNAPSHOT</version>
</parent>

<dependencies>
<dependency>
<groupId>io.github.martinschneider</groupId>
<artifactId>justtestlah-core</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>pCloudy-java-connector</groupId>
<artifactId>pCloudy-java-connector</artifactId>
<version>${pcloudy.connector.version}</version>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk</artifactId>
<version>${aws.sdk.version}</version>
</dependency>
<dependency>
<groupId>org.apache.maven.shared</groupId>
<artifactId>maven-invoker</artifactId>
<version>${maven.invoker.version}</version>
</dependency>
</dependencies>
</project>
@@ -0,0 +1,183 @@
package io.github.martinschneider.justtestlah.awsdevicefarm;

import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.services.devicefarm.AWSDeviceFarm;
import com.amazonaws.services.devicefarm.AWSDeviceFarmClient;
import com.amazonaws.services.devicefarm.AWSDeviceFarmClientBuilder;
import com.amazonaws.services.devicefarm.model.AWSDeviceFarmException;
import com.amazonaws.services.devicefarm.model.CreateUploadRequest;
import com.amazonaws.services.devicefarm.model.GetUploadRequest;
import com.amazonaws.services.devicefarm.model.GetUploadResult;
import com.amazonaws.services.devicefarm.model.Upload;
import com.amazonaws.services.devicefarm.model.UploadType;
import io.github.martinschneider.justtestlah.utils.FileEntity;
import java.io.File;
import java.io.IOException;
import java.util.Map;
import java.util.UUID;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/** Service class to interact with AWS, basically a wrapper around {@link AWSDeviceFarm}. */
public class AWSService {

private static final Logger LOG = LoggerFactory.getLogger(AWSService.class);

private AWSDeviceFarm aws;

/** Constructor */
public AWSService() {
aws = buildClient();
}

/**
* Constructor
*
* @param awsConfiguration key-value map holding AWS configuration
*/
public AWSService(Map<String, String> awsConfiguration) {

if (awsConfiguration == null) {
// use the default credentials provider
aws = buildClient();
} else {
String awsAccessKey = awsConfiguration.get("accessKey");
String awsSecretKey = awsConfiguration.get("secretKey");
String awsRegion = awsConfiguration.get("awsRegion");
if (awsAccessKey == null || awsSecretKey == null || awsRegion == null) {
// if any of the values is not set we use the default credentials provider
aws = buildClient();
} else {
aws = buildClient(awsAccessKey, awsSecretKey, awsRegion);
}
}
}

/**
* Constructor
*
* @param awsAccessKey the AWS access key
* @param awsSecretKey the AWS secret key
* @param awsRegion the AWS region
*/
public AWSService(String awsAccessKey, String awsSecretKey, String awsRegion) {
aws = buildClient(awsAccessKey, awsSecretKey, awsRegion);
}

/** @return {@link AWSDeviceFarm} */
public AWSDeviceFarm getAws() {
return aws;
}

private AWSDeviceFarm buildClient() {
LOG.debug("Building AWS Device Farm client using default credentials provider");
return AWSDeviceFarmClientBuilder.standard().build();
}

private AWSDeviceFarm buildClient(String awsAccessKey, String awsSecretKey, String awsRegion) {
LOG.debug("Building AWS Device Farm client");
LOG.debug("awsAccessKey={}", awsAccessKey);
LOG.debug("awsSecretKey={}", awsSecretKey);
LOG.debug("awsRegion={}", awsRegion);
return AWSDeviceFarmClient.builder()
.withCredentials(
new AWSStaticCredentialsProvider(new BasicAWSCredentials(awsAccessKey, awsSecretKey)))
.withRegion(awsRegion)
.build();
}

/**
* Upload a file to AWS Device Farm (modified from
* https://github.com/awslabs/aws-device-farm-jenkins-plugin)
*
* @param file the file to upload
* @param projectArn the ARN of the Device Farm project
* @param uploadType the {@link UploadType}
* @param synchronous true, if the execution should wait for the download to succeed
* @return {@link Upload}
* @throws InterruptedException {@link InterruptedException}
* @throws IOException {@link IOException}
* @throws AWSDeviceFarmException {@link AWSDeviceFarmException}
*/
public Upload upload(File file, String projectArn, UploadType uploadType, Boolean synchronous)
throws InterruptedException, IOException, AWSDeviceFarmException {
CreateUploadRequest appUploadRequest =
new CreateUploadRequest()
.withName(UUID.randomUUID() + "_" + file.getName())
.withProjectArn(projectArn)
.withContentType("application/octet-stream")
.withType(uploadType.toString());
Upload upload = aws.createUpload(appUploadRequest).getUpload();

CloseableHttpClient httpClient = HttpClients.createSystem();
HttpPut httpPut = new HttpPut(upload.getUrl());
httpPut.setHeader("Content-Type", upload.getContentType());

FileEntity entity = new FileEntity(file);
httpPut.setEntity(entity);

LOG.debug("AWS S3 upload URL: {}", upload.getUrl());

Thread thread =
new Thread() {
public void run() {
HttpResponse response = null;
try {
response = httpClient.execute(httpPut);
} catch (IOException exception) {
throw new AWSDeviceFarmException(
String.format("Error uploading file to AWS: %s", exception.getMessage()));
}
if (response.getStatusLine().getStatusCode() != 200) {
throw new AWSDeviceFarmException(
String.format(
"Upload returned non-200 responses: %d",
response.getStatusLine().getStatusCode()));
}
}
};
thread.start();
int progress = 0;
while (thread.isAlive()) {
int newProgress = entity.getProgress();
if (newProgress > progress) {
LOG.info("{}% completed {}", progress, file.getAbsolutePath());
progress = newProgress;
}
Thread.sleep(500);
}

if (synchronous) {
while (true) {
GetUploadRequest describeUploadRequest = new GetUploadRequest().withArn(upload.getArn());
GetUploadResult describeUploadResult = aws.getUpload(describeUploadRequest);
String status = describeUploadResult.getUpload().getStatus();

if ("SUCCEEDED".equalsIgnoreCase(status)) {
LOG.info("Uploading {} succeeded: {}", file.getName(), describeUploadRequest.getArn());
break;
} else if ("FAILED".equalsIgnoreCase(status)) {
LOG.info(
"Error message from device farm: '{}'",
describeUploadResult.getUpload().getMetadata());
throw new AWSDeviceFarmException(String.format("Upload %s failed!", upload.getName()));
} else {
try {
LOG.info(
"Waiting for upload {} to be ready (current status: {})", file.getName(), status);
Thread.sleep(5000);
} catch (InterruptedException exception) {
LOG.info("Thread interrupted while waiting for the upload to complete");
throw exception;
}
}
}
}
return upload;
}
}
Oops, something went wrong.

0 comments on commit 371fb1b

Please sign in to comment.
You can’t perform that action at this time.