Skip to content

Commit

Permalink
ci: add integration test with device farm (#56)
Browse files Browse the repository at this point in the history
  • Loading branch information
zhu-xiaowei authored Jan 9, 2024
1 parent 392f94a commit 2d342b9
Show file tree
Hide file tree
Showing 10 changed files with 708 additions and 22 deletions.
111 changes: 111 additions & 0 deletions .github/workflows/integration_test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
name: Integration Test

on:
pull_request:
branches: [ "main" ]

jobs:
test:
runs-on: ubuntu-latest
permissions:
contents: write
checks: write
pull-requests: write
id-token: write
env:
iam_role_to_assume: ${{ secrets.ROLE_ARN }}
device_farm_project_arn: ${{ secrets.DEVICE_FARM_PROJECT_ARN }}
device_farm_pool_arn: ${{ secrets.DEVICE_FARM_POOL_ARN }}
device_farm_test_spec_arn: ${{ secrets.DEVICE_FARM_TEST_SPEC_ARN }}
clickstream_app_id: ${{ secrets.CLICKSTREAM_APP_ID }}
clickstream_endpoint: ${{ secrets.CLICKSTREAM_ENDPOINT }}
steps:
- uses: actions/checkout@v4
- name: Set up JDK 8
uses: actions/setup-java@v4
with:
java-version: '8'
distribution: 'corretto'
cache: gradle
- name: Build SDK release aar file
run: |
echo ${{ github.event.pull_request.title }}
chmod +x gradlew
./gradlew assembleRelease
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'corretto'
cache: gradle
- name: Build sample android app
run: |
git clone https://github.com/aws-samples/clickstream-sdk-samples
mkdir clickstream-sdk-samples/android/app/libs/
cp -f clickstream/build/outputs/aar/clickstream-release.aar clickstream-sdk-samples/android/app/libs/
cd clickstream-sdk-samples/android
sed -i "s#\"appId\": \"your appId\"#\"appId\": \"${{ env.clickstream_app_id }}\"#g" app/src/main/res/raw/amplifyconfiguration.json
sed -i "s#\"endpoint\": \"your endpoint\"#\"endpoint\": \"${{ env.clickstream_endpoint }}\"#g" app/src/main/res/raw/amplifyconfiguration.json
cat app/src/main/res/raw/amplifyconfiguration.json
sed -i "s#implementation 'software.aws.solution:clickstream:0.10.0'#implementation(files(\"libs/clickstream-release.aar\"))\n implementation(\"com.amplifyframework:core:1.37.2\")\n implementation(\"com.amazonaws:aws-android-sdk-mobile-client:2.51.0\")\n implementation(\"com.squareup.okhttp3:okhttp:4.9.1\")#g" app/build.gradle
cat app/build.gradle
./gradlew assembleDebug
- name: Build Device Farm test file
run: |
cd integrationtest
pip install virtualenv
virtualenv --help
virtualenv workspace
cd workspace
source bin/activate
pip install pytest
pip install Appium-Python-Client
mkdir tests
cp ../appium/shopping_test.py tests/
find tests/
py.test --collect-only tests/
find . -name '__pycache__' -type d -exec rm -r {} +
find . -name '*.pyc' -exec rm -f {} +
find . -name '*.pyo' -exec rm -f {} +
find . -name '*~' -exec rm -f {} +
pip freeze > requirements.txt
zip -r test_bundle.zip tests/ requirements.txt
ls
cd ..
- name: Configure AWS Credentials
if: ${{ env.iam_role_to_assume != '' }}
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ env.iam_role_to_assume }}
aws-region: us-west-2
- name: Execute device farm test
run: |
cd integrationtest
pip install -r requirements.txt
cd devicefarm
cp ../../clickstream-sdk-samples/android/app/build/outputs/apk/debug/app-debug.apk ./
cp ../workspace/test_bundle.zip ./
ls
python -u -c "from automate_device_farm import upload_and_test_android; upload_and_test_android('app-debug.apk', 'test_bundle.zip', '${{ env.device_farm_project_arn }}', '${{ env.device_farm_test_spec_arn }}', '${{ env.device_farm_pool_arn }}')"
- name: Execute logcat test
run: |
cd integrationtest/devicefarm
pytest logcat_test.py -s --junitxml=report/logcat_test_report.xml --html=report/logcat_test_report.html
- name: Publish Test Report
uses: mikepenz/action-junit-report@v4
if: success() || failure()
with:
report_paths: 'integrationtest/devicefarm/report/*.xml'
require_tests: true
detailed_summary: true
include_passed: true
fail_on_failure: true
job_name: integration test
- name: Upload test result
uses: actions/upload-artifact@v4
if: success() || failure()
with:
name: test-result
path: |
integrationtest/devicefarm/report/
integrationtest/devicefarm/MyAndroidAppTest-*/**
47 changes: 26 additions & 21 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ on:
env:
NEW_VERSION: ${{ github.event.inputs.release_tag }}
jobs:
release:
release-pr:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
ref: main
fetch-depth: 0
Expand All @@ -24,23 +24,28 @@ jobs:
chmod +x release.sh
./release.sh ${{ env.NEW_VERSION }}
git diff
git config user.name '${{ vars.USER_NAME }}'
git config user.email '${{ vars.USER_EMAIL }}'
git add .
git commit -m 'release: clickstream Android ${{ env.NEW_VERSION }}'
git push
git tag v${{ env.NEW_VERSION }}
git push origin v${{ env.NEW_VERSION }}
- name: Assemble release
run: |
chmod +x gradlew
./gradlew assembleRelease
- name: Create GitHub release
uses: softprops/action-gh-release@v1
git config user.name "github-actions"
git config user.email "[email protected]"
- name: Create Pull Request
id: create-pr
uses: peter-evans/create-pull-request@v5
with:
name: "Clickstream Android ${{ env.NEW_VERSION }}"
files: |
clickstream/build/outputs/aar/clickstream-release.aar
tag_name: "v${{ env.NEW_VERSION }}"
prerelease: true
generate_release_notes: true
token: ${{ secrets.PROJECT_TOKEN }}
commit-message: 'release: clickstream Android ${{ env.NEW_VERSION }}'
title: 'release: clickstream Android ${{ env.NEW_VERSION }}'
author: github-actions <[email protected]>
committer: github-actions <[email protected]>
signoff: true
body: |
- [x] PR title and description conform to [Pull Request](https://github.com/awslabs/clickstream-android/blob/main/CONTRIBUTING.md#pull-request-guidelines) guidelines.
*Description of changes:*
1. release: clickstream Android ${{ env.NEW_VERSION }}
*Documentation update required?*
- [ ] No
- [x] Yes (Please include a PR link for the documentation update)
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
labels: release
branch: release_${{ env.NEW_VERSION }}
42 changes: 42 additions & 0 deletions .github/workflows/tag_and_release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
name: Create Tag And Release
on:
push:
branches: [ "main" ]

jobs:
release:
if: ${{ startsWith(github.event.head_commit.message, 'release:') }}
runs-on: ubuntu-latest
env:
COMMIT_MESSAGE: ${{ github.event.head_commit.message }}
permissions:
contents: write
steps:
- uses: actions/checkout@v4
with:
ref: main
fetch-depth: 0
token: ${{ secrets.PROJECT_TOKEN }}
- name: Create new tag
run: |
echo "${{ env.COMMIT_MESSAGE }}"
version=$(echo "${{ env.COMMIT_MESSAGE }}" | grep -oP 'Android \K\d+\.\d+\.\d+')
echo "release_version=$version" >> "$GITHUB_ENV"
echo $version
git config user.name '${{ vars.USER_NAME }}'
git config user.email '${{ vars.USER_EMAIL }}'
git tag v$version
git push origin v$version
- name: Assemble release
run: |
chmod +x gradlew
./gradlew assembleRelease
- name: Create GitHub release
uses: softprops/action-gh-release@v1
with:
name: "Clickstream Android $release_version"
files: |
clickstream/build/outputs/aar/clickstream-release.aar
tag_name: "v$release_version"
prerelease: true
generate_release_notes: true
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -101,3 +101,7 @@ build-artifacts.tar.gz

# add ignore for jenv
.java-version

# python
venv
*.idea
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ public void recordUserEngagement() {
* the method for flush events when app move to background.
*/
public void flushEvents() {
LOG.debug("App moves to background and start to flush events");
this.clickstreamContext.getAnalyticsClient().submitEvents();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -502,7 +502,7 @@ public void testRecordEventWithSubmitterTwice() throws Exception {
.add("Successful", true)
.add("ProcessDuration", 792)
.add("UserAge", 120.3);
String longString = analyticsClient.createEvent("testEvent").toString();
String longString = analyticsClient.createEvent("testEvent").toString().substring(0, 1020);
for (int i = 0; i < 80; i++) {
builder.add("str" + i, longString);
}
Expand Down
110 changes: 110 additions & 0 deletions integrationtest/appium/shopping_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
"""
Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance
with the License. A copy of the License is located at
http://www.apache.org/licenses/LICENSE-2.0
or in the 'license' file accompanying this file. This file is distributed on an 'AS IS' BASIS, WITHOUT WARRANTIES
OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions
and limitations under the License.
"""
import pytest
from time import sleep

from appium import webdriver
from appium.options.android import UiAutomator2Options
from appium.webdriver.common.appiumby import AppiumBy

capabilities = dict(
platformName='Android',
automationName='uiautomator2',
deviceName='Android',
appPackage='com.kanyideveloper.joomia',
appActivity='.core.presentation.MainActivity',
language='en',
locale='US',
)

appium_server_url = 'http://0.0.0.0:4723/wd/hub'


class TestShopping:
def setup(self):
self.driver = webdriver.Remote(appium_server_url, options=UiAutomator2Options().load_capabilities(capabilities))
self.driver.implicitly_wait(10)

def teardown(self):
if self.driver:
self.driver.quit()

@pytest.mark.parametrize("user_name,password", [
("user1", "password1"),
("user2", "password2"),
])
def test_shopping(self, user_name, password):
# login
username_et = self.find_element("userName")
username_et.send_keys(user_name)
password_et = self.find_element("password")
password_et.send_keys(password)
signin_bt = self.find_element("signIn")
signin_bt.click()
sleep(3)

# add 2 product to cart
product_1 = self.find_element('product0')
sleep(1)
product_1.click()
add_to_cart1 = self.find_element('add_to_cart_button')
sleep(1)
add_to_cart1.click()
sleep(1)
self.driver.press_keycode(4)

product_2 = self.find_element('product1')
sleep(1)
product_2.click()
add_to_cart2 = self.find_element('add_to_cart_button')
sleep(1)
add_to_cart2.click()
sleep(1)
self.driver.press_keycode(4)

# click 1 product to wishlist
product_3 = self.find_element('product2')
sleep(1)
product_3.click()
like_button = self.find_element('like_button')
sleep(1)
like_button.click()
sleep(1)
self.driver.press_keycode(4)
sleep(1)
wishlist_tab = self.find_element('homeTab1')
wishlist_tab.click()
sleep(1)

cart_tab = self.find_element('homeTab2')
cart_tab.click()
checkout_bt = self.find_element('check_out_button')
sleep(1)
checkout_bt.click()

profile_tab = self.find_element('homeTab3')
sleep(1)
profile_tab.click()
sign_out_bt = self.find_element('sign_out_button')
sleep(1)
sign_out_bt.click()
self.driver.press_keycode(3)
sleep(5)

def find_element(self, name):
return self.driver.find_element(AppiumBy.ANDROID_UIAUTOMATOR,
value='new UiSelector().resourceId("' + name + '")')


if __name__ == '__main__':
TestShopping.test_shopping()
Loading

0 comments on commit 2d342b9

Please sign in to comment.