Skip to content

Commit

Permalink
Merge pull request #4 from garcanam/feature/appium_mobile
Browse files Browse the repository at this point in the history
Feature/appium mobile
  • Loading branch information
garcanam authored Dec 13, 2024
2 parents 0746e47 + c796f0f commit 856246e
Show file tree
Hide file tree
Showing 27 changed files with 1,201 additions and 258 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
- Added new function to cypress to log into applications using MFA ([#1070](https://github.com/opendevstack/ods-quickstarters/pull/1070))
- Removal of deprecated versions ([#1068](https://github.com/opendevstack/ods-quickstarters/issues/1068))
- Generate PDF report for cypress and improved environment management ([#1079](https://github.com/opendevstack/ods-quickstarters/pull/1079))
- Mobile testing enablement adding Appium in e2e-spock-geb quickstarter

### Added

Expand Down
122 changes: 93 additions & 29 deletions docs/modules/quickstarters/pages/e2e-spock-geb.adoc
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
= End-to-end tests with Spock, Geb and Unirest (e2e-spock-geb)
= End-to-end tests with Spock, Geb, Unirest, and Appium (e2e-spock-geb)

spock, geb and unirest e2e testing quickstarter project
Spock, Geb, Unirest, and Appium e2e testing quickstarter project

== Purpose of this quickstarter

This is a spock, geb and unirest e2e testing project quickstarter with basic setup for https://jenkins.io/[Jenkins], https://www.sonarqube.org/[SonarQube] and https://gradle.org/[Gradle].
This is a Spock, Geb, Unirest, and Appium e2e testing project quickstarter with basic setup for https://jenkins.io/[Jenkins], https://www.sonarqube.org/[SonarQube], https://gradle.org/[Gradle], and https://appium.io/[Appium].

== What files / architecture is generated?

Expand All @@ -18,7 +18,15 @@ This is a spock, geb and unirest e2e testing project quickstarter with basic set
│ ├── test
│ │ └── acceptance
│ │ │ └── groovy
│ │ │ │ └── DemoAcceptanceSpec.groovy
│ │ │ │ └── modules
│ │ │ │ └── DemoManualMenuModule.groovy
│ │ │ │ └── pages
│ │ │ │ └── DemoGebHomePage.groovy
│ │ │ │ └── DemoTheBookOfGebPage.groovy
│ │ │ │ └── specs
│ │ │ │ └── DemoGebHomePageSpec.groovy
│ │ │ │ └── DemoMobileAppSpec.groovy
│ │ │ │ └── DemoMobileGebHomePageSpec.groovy
│ │ │ └── java
│ │ │ └── DemoAcceptanceTest.java
│ │ └── installation
Expand All @@ -30,11 +38,13 @@ This is a spock, geb and unirest e2e testing project quickstarter with basic set
│ │ │ └── groovy
│ │ │ │ └── DemoIntegrationSpec.groovy
│ │ │ └── java
│ │ | └── DemoIntegrationTest.java
│ │ └── DemoIntegrationTest.java
│ │ └── resources
│ │ └── application.properties
│ │ └── GebConfig.groovy
│ │ └── SpecHelper.groovy
│ │ │ └── helpers
│ │ │ └── Environments.groovy
│ │ │ └── SpecHelper.groovy
│ │ │ └── application.properties
│ │ │ └── GebConfig.groovy
├── gradle
│ └── wrapper
│ ├── gradle-wrapper.jar
Expand Down Expand Up @@ -77,47 +87,103 @@ no_nexus=true

Run `gradlew -v` to verify the installed version of gradle wrapper.

== Frameworks used
=== Environments Configuration

This project is generated by https://gradle.org/[Gradle]
The environments used in the tests are defined in the `build.gradle` file. You can find the environments under the `ext` block as project properties. These environments are accessed via system properties in the Groovy classes. Here is an example of how the environments are defined:
```
ext {
...
environments = [
DESKTOP: "desktop",
MOBILE_BROWSER: "mobile_browser",
MOBILE_APP: "mobile_app"
]
}
...
tasks.withType(Test) {
systemProperty 'environments.desktop', environments.DESKTOP
systemProperty 'environments.mobile_browser', environments.MOBILE_BROWSER
systemProperty 'environments.mobile_app', environments.MOBILE_APP
}
```

******* http://spockframework.org/[spock]
Additionally, there is a class called `Environments.groovy` that facilitates access to these environments from the Groovy code. The class is located in the `src/test/resources/helpers` directory.
```
package helpers

class Environments {
// Define environment constants using system properties
// Check the build.gradle file for the defined properties
static final String DESKTOP = System.getProperty('environments.desktop')
static final String MOBILE_BROWSER = System.getProperty('environments.mobile_browser')
static final String MOBILE_APP = System.getProperty('environments.mobile_app')
}
```

******* https://gebish.org/[geb]
== Sauce Labs Integration

******* http://unirest.io/[unirest]
Sauce Labs is a cloud-based platform that provides comprehensive testing solutions for web and mobile applications. It allows you to run tests on a wide range of real devices and emulators/simulators, ensuring your applications work seamlessly across different environments.

This template is prepared to work with Sauce Labs virtual devices, allowing you to perform all mobile tests on these virtual devices.

=== Key Features of Sauce Labs

* **Real Device Cloud**: Access to thousands of real Android and iOS devices for manual and automated testing.
* **Emulators and Simulators**: Cost-effective and scalable testing on virtual devices.
* **Cross-Browser Testing**: Ensure compatibility across various browser and OS combinations.
* **Error Monitoring and Reporting**: Capture and resolve application errors quickly with detailed insights.
* **CI/CD Integration**: Seamlessly integrate with your continuous integration and delivery pipelines.

=== How to use it

## Usage - how do you start after you provisioned this quickstarter
To use Sauce Labs, a secret will be created by default where the `username` and `accessKey` necessary to execute the test cases in Sauce Labs will be stored. By default, these values will be set to "changeme". Once you have obtained your Sauce Labs username and access key, you should modify the secret data to start interacting with Sauce Labs.

* Run command `gradlew test` in project directory to execute the end-to-end tests via spock/geb against the Google Home page and demo jUnit 5 tests.
== Usage - how do you start after you provisioned this quickstarter

* Run command `gradlew test` in project directory to execute the end-to-end tests via spock/geb against the demo pages and demo jUnit 5 tests.

You will see the results inside a new folder 'build' in project directory.

----
.
└── build
└── test-results
├── acceptance-groovy
│ └── TEST-DemoAcceptance.xml
├── acceptance-java
│ └── TEST-DemoAcceptanceTest.xml
├── installation-groovy
│ └── TEST-DemoInstallation.xml
├── installation-java
├── acceptance-groovy-desktop
├── acceptance-java-desktop
│ │── TEST-DemoAcceptanceTest.xml
│ │── TEST-specs.DemoGebHomePageSpec.xml
│ │── TEST-specs.DemoMobileAppSpec.xml
│ └── TEST-specs.DemoMobileGebHomePageSpec.xml
├── installation-groovy-desktop
├── installation-java-desktop
│ │── TEST-DemoInstallationSpec.xml
│ └── TEST-DemoInstallationTest.xml
├── integration-groovy
└── TEST-DemoIntegration.xml
── integration-java
├── integration-groovy-desktop
└── integration-java-desktop
── TEST-DemoIntegrationSpec.xml
└── TEST-DemoIntegrationTest.xml
----
== Frameworks used

This project is generated by https://gradle.org/[Gradle]

******* http://spockframework.org/[spock]

******* https://gebish.org/[geb]

******* http://unirest.io/[unirest]

******* https://appium.io/[apium]

******* https://saucelabs.com/[Sauce Labs]

## Customization - how do you start to configure your test

* You can see how a Java Junit 5 test are developed showing the Demo*Test.java files.
* You can see how a Groovy Spock/Geb test are developed showing the Demo*Spec.groovy files.
** The url to test with Geb is configured in the property `config.application.url` inside `application.properties`
** Inside `GebConfig.groovy` you could change the default navigator (CHROME)
** Inside `GebConfig.groovy` you could see some environments with different drivers defined and a default browser. You could configure or change them as you need.

== How this quickstarter is built through jenkins

Expand All @@ -134,13 +200,11 @@ In Jenkinsfile.template, there is the following stage:

All the results are stashed and published through Jenkins jUnit publisher.

include::partials$secret-scanning-with-gitleaks.adoc

== Builder agent used

This quickstarter uses the
https://github.com/opendevstack/ods-quickstarters/tree/master/common/jenkins-agents/jdk[jdk] Jenkins builder agent.

== Known limitations

NA
NA
18 changes: 18 additions & 0 deletions e2e-spock-geb/Jenkinsfile
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,24 @@ odsQuickstarterPipeline(
odsQuickstarterStageCopyFiles(context)

odsQuickstarterStageRenderJenkinsfile(context)

createSauceLabsOpenshiftSecret(context)

odsQuickstarterStageRenderSonarProperties(context)
}

def createSauceLabsOpenshiftSecret(def context) {
stage('Create Credentials') {
def project = context.projectId + "-cd"
def secretExists = sh(script: "oc get secret sauce-labs-user-access-key -n $project", returnStatus: true) == 0
if (!secretExists) {
sh """
oc create secret generic sauce-labs-user-access-key -n $project \
--from-literal=username=changeme \
--from-literal=password=changeme \
--type="kubernetes.io/basic-auth" && \
oc label secret sauce-labs-user-access-key -n $project credential.sync.jenkins.openshift.io=true
"""
}
}
}
56 changes: 46 additions & 10 deletions e2e-spock-geb/Jenkinsfile.template
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
// See https://www.opendevstack.org/ods-documentation/ for usage and customization.

@Library('ods-jenkins-shared-library@@shared_library_ref@') _
node {
dockerRegistry = env.DOCKER_REGISTRY
}

odsComponentPipeline(
imageStreamTag: '@ods_namespace@/jenkins-agent-jdk:@agent_image_tag@',
Expand All @@ -21,16 +24,49 @@ def stageTest(def context) {
springBootEnv = 'dev'
}

stage('Integration Test') {
sh (script: "chmod a+x gradle*", label : "allow gradle to execute")
withEnv(["TAGVERSION=${context.tagversion}", "NEXUS_HOST=${context.nexusHost}", "NEXUS_USERNAME=${context.nexusUsername}", "NEXUS_PASSWORD=${context.nexusPassword}", "JAVA_OPTS=${javaOpts}","GRADLE_TEST_OPTS=${gradleTestOpts}","ENVIRONMENT=${springBootEnv}","OPENSHIFT_PROJECT=${context.targetProject}","OPENSHIFT_APP_DOMAIN=${context.getOpenshiftApplicationDomain()}"]) {
def status = sh(script: "./gradlew clean test --stacktrace --no-daemon", returnStatus: true)
junit(testResults:"build/test-results/installation*/*.xml, build/test-results/integration*/*.xml, build/test-results/acceptance*/*.xml", allowEmptyResults:true)
stash(name: "installation-test-reports-junit-xml-${context.componentId}-${context.buildNumber}", includes: 'build/test-results/installation*/*.xml', allowEmpty: true)
stash(name: "integration-test-reports-junit-xml-${context.componentId}-${context.buildNumber}", includes: 'build/test-results/integration*/*.xml', allowEmpty: true)
stash(name: "acceptance-test-reports-junit-xml-${context.componentId}-${context.buildNumber}", includes: 'build/test-results/acceptance*/*.xml', allowEmpty: true)
if (status != 0) {
error "Executing tests failed!"
stage('Functional Test') {
sh (script: "chmod a+x gradle*", label : "allow gradle to execute")
withEnv([
"TAGVERSION=${context.tagversion}",
"NEXUS_HOST=${context.nexusHost}",
"NEXUS_USERNAME=${context.nexusUsername}",
"NEXUS_PASSWORD=${context.nexusPassword}",
"JAVA_OPTS=${javaOpts}",
"GRADLE_TEST_OPTS=${gradleTestOpts}",
"ENVIRONMENT=${springBootEnv}",
"OPENSHIFT_PROJECT=${context.targetProject}",
"OPENSHIFT_APP_DOMAIN=${context.getOpenshiftApplicationDomain()}"
]) {
withCredentials([
usernamePassword(credentialsId: "${context.projectId}-cd-sauce-labs-user-access-key", passwordVariable: 'SAUCE_LABS_ACCESS_KEY', usernameVariable: 'SAUCE_LABS_USERNAME'),
]) {
// Note: Testing in the production environment is not enabled by default as it can lead to unintended consequences,
// including potential downtime, data corruption, or exposure of sensitive information.
// This block is designed to skip acceptance and integration tests in the production environment to avoid these risks.
// If you choose to enable these tests in production take all necessary precautions. This means verifying your
// preconditions, database access, fake data, API calls, etc.
// Remember that any test case in the installation folder will be executed in production.
def status
if (context.environment == 'prod') {
status = sh(script: './gradlew clean testProd --stacktrace --no-daemon', returnStatus: true)
junit(testResults:"build/test-results/installation*/*.xml", allowEmptyResults:true)
stash(name: "installation-test-reports-junit-xml-${context.componentId}-${context.buildNumber}", includes: 'build/test-results/installation*/*.xml', allowEmpty: true)
} else {
status = sh(script: './gradlew clean test --stacktrace --no-daemon', returnStatus: true)
junit(testResults:"build/test-results/installation*/*.xml, build/test-results/integration*/*.xml, build/test-results/acceptance*/*.xml", allowEmptyResults:true)
stash(name: "installation-test-reports-junit-xml-${context.componentId}-${context.buildNumber}", includes: 'build/test-results/installation*/*.xml', allowEmpty: true)
stash(name: "integration-test-reports-junit-xml-${context.componentId}-${context.buildNumber}", includes: 'build/test-results/integration*/*.xml', allowEmpty: true)
stash(name: "acceptance-test-reports-junit-xml-${context.componentId}-${context.buildNumber}", includes: 'build/test-results/acceptance*/*.xml', allowEmpty: true)
}

// Handle the test status
switch (status) {
case 0:
echo "All tests passed successfully"
break
default:
unstable "Some tests have failed or encountered errors. Please check the logs for more details."
}
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion e2e-spock-geb/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@

Documentation is located in our [official documentation](https://www.opendevstack.org/ods-documentation/opendevstack/3.x/quickstarters/e2e-spock-geb.html)

Please update documentation in the [antora page directory](https://github.com/opendevstack/ods-project-quickstarters/tree/master/docs/modules/ROOT/pages)
Please update documentation in the [antora page directory](https://github.com/opendevstack/ods-quickstarters/tree/master/docs/modules/ROOT/pages)

Tested thru [automated tests](../tests/e2e-spock-geb)
2 changes: 1 addition & 1 deletion e2e-spock-geb/files/.pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
repos:
- repo: https://github.com/gitleaks/gitleaks
rev: v8.18.4
rev: v8.16.1
hooks:
- id: gitleaks
Loading

0 comments on commit 856246e

Please sign in to comment.