Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ci: add integration test with device farm #56

Merged
merged 46 commits into from
Jan 9, 2024
Merged
Show file tree
Hide file tree
Changes from 38 commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
c0de016
feat: add integration test
Jan 4, 2024
a4dd6c0
feat: split to different jobs
Jan 4, 2024
4c49291
feat: test build
Jan 4, 2024
fab753f
feat: install virtualenv
Jan 4, 2024
d623954
feat: add permissions
Jan 4, 2024
6b959e1
feat: test new arn
Jan 4, 2024
d257a46
feat: test pip install
Jan 4, 2024
b874a89
feat: test build apk and upload to devicefarm
Jan 4, 2024
cdb6a86
feat: fix apk path
Jan 4, 2024
ce532ec
feat: fix python method upload_df_file
Jan 4, 2024
b97db48
feat: test unzip and tree
Jan 4, 2024
ce956cc
feat: test unzip and print tree
Jan 4, 2024
c48d808
feat: test Upload test result
Jan 4, 2024
cd50ee8
feat: test Upload final test bundle
Jan 4, 2024
7cf11ee
feat: revert code
Jan 4, 2024
0dda5ac
fix: upload_df_file parameters
Jan 4, 2024
2315a4a
feat: test delete Set up JDK 17
Jan 4, 2024
1f3d5b1
feat: add setup java17
Jan 4, 2024
3727a59
feat: add python realtime output
Jan 4, 2024
2aaf6d1
feat: split logcat test and add report upload
Jan 5, 2024
32c8631
feat: add pytest-html
Jan 5, 2024
5bdd496
feat: test output log
Jan 5, 2024
64ffbb0
feat: test copy aar and modify configuration
Jan 5, 2024
5aba207
feat: test copy
Jan 5, 2024
d2f5048
feat: change to #
Jan 5, 2024
d375c7e
feat: test create pr
Jan 8, 2024
59c03f3
feat: test head_commit message
Jan 8, 2024
037c962
fix: trigger condition
Jan 8, 2024
9f0728d
fix: integration test with longString exceed 1024
Jan 8, 2024
61a7b25
feat: add logcat test case
Jan 8, 2024
d043ed4
feat: make integration test run on each pr
Jan 8, 2024
19fd2dc
fix: change build apk branch to integration_test
Jan 9, 2024
c6edcfe
fix: change integration workflow job name
Jan 9, 2024
7757e80
fix: format event json failed
Jan 9, 2024
110eebe
fix: fix logcat test assert
Jan 9, 2024
6e7c1d3
feat: split to different test case
Jan 9, 2024
1488865
fix: the comment in logcat test
Jan 9, 2024
ae8e21c
fix: events not sent completely
Jan 9, 2024
52f221d
fix: change to fork android app form main branch
Jan 9, 2024
a87dcd3
fix: optimize report and add appium test report
Jan 9, 2024
94bf706
fix: change zip file path
Jan 9, 2024
2c1e338
fix: makedirs fail
Jan 9, 2024
71da69a
feat: optimize report name
Jan 9, 2024
7ae1c9f
fix: remove update_check
Jan 9, 2024
586fa59
feat: add license header in pytest file
Jan 9, 2024
03186f3
fix: logcat event lost
Jan 9, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
103 changes: 103 additions & 0 deletions .github/workflows/integration_test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
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 -b integration_test https://github.com/aws-samples/clickstream-sdk-samples
zhu-xiaowei marked this conversation as resolved.
Show resolved Hide resolved
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
./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'
- 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
98 changes: 98 additions & 0 deletions integrationtest/appium/shopping_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
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
Loading