Skip to content

Commit 2d342b9

Browse files
authored
ci: add integration test with device farm (#56)
1 parent 392f94a commit 2d342b9

File tree

10 files changed

+708
-22
lines changed

10 files changed

+708
-22
lines changed
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
name: Integration Test
2+
3+
on:
4+
pull_request:
5+
branches: [ "main" ]
6+
7+
jobs:
8+
test:
9+
runs-on: ubuntu-latest
10+
permissions:
11+
contents: write
12+
checks: write
13+
pull-requests: write
14+
id-token: write
15+
env:
16+
iam_role_to_assume: ${{ secrets.ROLE_ARN }}
17+
device_farm_project_arn: ${{ secrets.DEVICE_FARM_PROJECT_ARN }}
18+
device_farm_pool_arn: ${{ secrets.DEVICE_FARM_POOL_ARN }}
19+
device_farm_test_spec_arn: ${{ secrets.DEVICE_FARM_TEST_SPEC_ARN }}
20+
clickstream_app_id: ${{ secrets.CLICKSTREAM_APP_ID }}
21+
clickstream_endpoint: ${{ secrets.CLICKSTREAM_ENDPOINT }}
22+
steps:
23+
- uses: actions/checkout@v4
24+
- name: Set up JDK 8
25+
uses: actions/setup-java@v4
26+
with:
27+
java-version: '8'
28+
distribution: 'corretto'
29+
cache: gradle
30+
- name: Build SDK release aar file
31+
run: |
32+
echo ${{ github.event.pull_request.title }}
33+
chmod +x gradlew
34+
./gradlew assembleRelease
35+
- name: Set up JDK 17
36+
uses: actions/setup-java@v4
37+
with:
38+
java-version: '17'
39+
distribution: 'corretto'
40+
cache: gradle
41+
- name: Build sample android app
42+
run: |
43+
git clone https://github.com/aws-samples/clickstream-sdk-samples
44+
mkdir clickstream-sdk-samples/android/app/libs/
45+
cp -f clickstream/build/outputs/aar/clickstream-release.aar clickstream-sdk-samples/android/app/libs/
46+
cd clickstream-sdk-samples/android
47+
sed -i "s#\"appId\": \"your appId\"#\"appId\": \"${{ env.clickstream_app_id }}\"#g" app/src/main/res/raw/amplifyconfiguration.json
48+
sed -i "s#\"endpoint\": \"your endpoint\"#\"endpoint\": \"${{ env.clickstream_endpoint }}\"#g" app/src/main/res/raw/amplifyconfiguration.json
49+
cat app/src/main/res/raw/amplifyconfiguration.json
50+
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
51+
cat app/build.gradle
52+
./gradlew assembleDebug
53+
- name: Build Device Farm test file
54+
run: |
55+
cd integrationtest
56+
pip install virtualenv
57+
virtualenv --help
58+
virtualenv workspace
59+
cd workspace
60+
source bin/activate
61+
pip install pytest
62+
pip install Appium-Python-Client
63+
mkdir tests
64+
cp ../appium/shopping_test.py tests/
65+
find tests/
66+
py.test --collect-only tests/
67+
find . -name '__pycache__' -type d -exec rm -r {} +
68+
find . -name '*.pyc' -exec rm -f {} +
69+
find . -name '*.pyo' -exec rm -f {} +
70+
find . -name '*~' -exec rm -f {} +
71+
pip freeze > requirements.txt
72+
zip -r test_bundle.zip tests/ requirements.txt
73+
ls
74+
cd ..
75+
- name: Configure AWS Credentials
76+
if: ${{ env.iam_role_to_assume != '' }}
77+
uses: aws-actions/configure-aws-credentials@v4
78+
with:
79+
role-to-assume: ${{ env.iam_role_to_assume }}
80+
aws-region: us-west-2
81+
- name: Execute device farm test
82+
run: |
83+
cd integrationtest
84+
pip install -r requirements.txt
85+
cd devicefarm
86+
cp ../../clickstream-sdk-samples/android/app/build/outputs/apk/debug/app-debug.apk ./
87+
cp ../workspace/test_bundle.zip ./
88+
ls
89+
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 }}')"
90+
- name: Execute logcat test
91+
run: |
92+
cd integrationtest/devicefarm
93+
pytest logcat_test.py -s --junitxml=report/logcat_test_report.xml --html=report/logcat_test_report.html
94+
- name: Publish Test Report
95+
uses: mikepenz/action-junit-report@v4
96+
if: success() || failure()
97+
with:
98+
report_paths: 'integrationtest/devicefarm/report/*.xml'
99+
require_tests: true
100+
detailed_summary: true
101+
include_passed: true
102+
fail_on_failure: true
103+
job_name: integration test
104+
- name: Upload test result
105+
uses: actions/upload-artifact@v4
106+
if: success() || failure()
107+
with:
108+
name: test-result
109+
path: |
110+
integrationtest/devicefarm/report/
111+
integrationtest/devicefarm/MyAndroidAppTest-*/**

.github/workflows/release.yml

Lines changed: 26 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,12 @@ on:
99
env:
1010
NEW_VERSION: ${{ github.event.inputs.release_tag }}
1111
jobs:
12-
release:
12+
release-pr:
1313
runs-on: ubuntu-latest
1414
permissions:
1515
contents: write
1616
steps:
17-
- uses: actions/checkout@v3
17+
- uses: actions/checkout@v4
1818
with:
1919
ref: main
2020
fetch-depth: 0
@@ -24,23 +24,28 @@ jobs:
2424
chmod +x release.sh
2525
./release.sh ${{ env.NEW_VERSION }}
2626
git diff
27-
git config user.name '${{ vars.USER_NAME }}'
28-
git config user.email '${{ vars.USER_EMAIL }}'
29-
git add .
30-
git commit -m 'release: clickstream Android ${{ env.NEW_VERSION }}'
31-
git push
32-
git tag v${{ env.NEW_VERSION }}
33-
git push origin v${{ env.NEW_VERSION }}
34-
- name: Assemble release
35-
run: |
36-
chmod +x gradlew
37-
./gradlew assembleRelease
38-
- name: Create GitHub release
39-
uses: softprops/action-gh-release@v1
27+
git config user.name "github-actions"
28+
git config user.email "github-actions@github.com"
29+
- name: Create Pull Request
30+
id: create-pr
31+
uses: peter-evans/create-pull-request@v5
4032
with:
41-
name: "Clickstream Android ${{ env.NEW_VERSION }}"
42-
files: |
43-
clickstream/build/outputs/aar/clickstream-release.aar
44-
tag_name: "v${{ env.NEW_VERSION }}"
45-
prerelease: true
46-
generate_release_notes: true
33+
token: ${{ secrets.PROJECT_TOKEN }}
34+
commit-message: 'release: clickstream Android ${{ env.NEW_VERSION }}'
35+
title: 'release: clickstream Android ${{ env.NEW_VERSION }}'
36+
author: github-actions <github-actions@github.com>
37+
committer: github-actions <github-actions@github.com>
38+
signoff: true
39+
body: |
40+
- [x] PR title and description conform to [Pull Request](https://github.com/awslabs/clickstream-android/blob/main/CONTRIBUTING.md#pull-request-guidelines) guidelines.
41+
42+
*Description of changes:*
43+
1. release: clickstream Android ${{ env.NEW_VERSION }}
44+
45+
*Documentation update required?*
46+
- [ ] No
47+
- [x] Yes (Please include a PR link for the documentation update)
48+
49+
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
50+
labels: release
51+
branch: release_${{ env.NEW_VERSION }}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
name: Create Tag And Release
2+
on:
3+
push:
4+
branches: [ "main" ]
5+
6+
jobs:
7+
release:
8+
if: ${{ startsWith(github.event.head_commit.message, 'release:') }}
9+
runs-on: ubuntu-latest
10+
env:
11+
COMMIT_MESSAGE: ${{ github.event.head_commit.message }}
12+
permissions:
13+
contents: write
14+
steps:
15+
- uses: actions/checkout@v4
16+
with:
17+
ref: main
18+
fetch-depth: 0
19+
token: ${{ secrets.PROJECT_TOKEN }}
20+
- name: Create new tag
21+
run: |
22+
echo "${{ env.COMMIT_MESSAGE }}"
23+
version=$(echo "${{ env.COMMIT_MESSAGE }}" | grep -oP 'Android \K\d+\.\d+\.\d+')
24+
echo "release_version=$version" >> "$GITHUB_ENV"
25+
echo $version
26+
git config user.name '${{ vars.USER_NAME }}'
27+
git config user.email '${{ vars.USER_EMAIL }}'
28+
git tag v$version
29+
git push origin v$version
30+
- name: Assemble release
31+
run: |
32+
chmod +x gradlew
33+
./gradlew assembleRelease
34+
- name: Create GitHub release
35+
uses: softprops/action-gh-release@v1
36+
with:
37+
name: "Clickstream Android $release_version"
38+
files: |
39+
clickstream/build/outputs/aar/clickstream-release.aar
40+
tag_name: "v$release_version"
41+
prerelease: true
42+
generate_release_notes: true

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,3 +101,7 @@ build-artifacts.tar.gz
101101

102102
# add ignore for jenv
103103
.java-version
104+
105+
# python
106+
venv
107+
*.idea

clickstream/src/main/java/software/aws/solution/clickstream/client/AutoRecordEventClient.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ public void recordUserEngagement() {
147147
* the method for flush events when app move to background.
148148
*/
149149
public void flushEvents() {
150+
LOG.debug("App moves to background and start to flush events");
150151
this.clickstreamContext.getAnalyticsClient().submitEvents();
151152
}
152153

clickstream/src/test/java/software/aws/solution/clickstream/IntegrationTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -502,7 +502,7 @@ public void testRecordEventWithSubmitterTwice() throws Exception {
502502
.add("Successful", true)
503503
.add("ProcessDuration", 792)
504504
.add("UserAge", 120.3);
505-
String longString = analyticsClient.createEvent("testEvent").toString();
505+
String longString = analyticsClient.createEvent("testEvent").toString().substring(0, 1020);
506506
for (int i = 0; i < 80; i++) {
507507
builder.add("str" + i, longString);
508508
}
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
"""
2+
Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance
5+
with the License. A copy of the License is located at
6+
7+
http://www.apache.org/licenses/LICENSE-2.0
8+
9+
or in the 'license' file accompanying this file. This file is distributed on an 'AS IS' BASIS, WITHOUT WARRANTIES
10+
OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions
11+
and limitations under the License.
12+
"""
13+
import pytest
14+
from time import sleep
15+
16+
from appium import webdriver
17+
from appium.options.android import UiAutomator2Options
18+
from appium.webdriver.common.appiumby import AppiumBy
19+
20+
capabilities = dict(
21+
platformName='Android',
22+
automationName='uiautomator2',
23+
deviceName='Android',
24+
appPackage='com.kanyideveloper.joomia',
25+
appActivity='.core.presentation.MainActivity',
26+
language='en',
27+
locale='US',
28+
)
29+
30+
appium_server_url = 'http://0.0.0.0:4723/wd/hub'
31+
32+
33+
class TestShopping:
34+
def setup(self):
35+
self.driver = webdriver.Remote(appium_server_url, options=UiAutomator2Options().load_capabilities(capabilities))
36+
self.driver.implicitly_wait(10)
37+
38+
def teardown(self):
39+
if self.driver:
40+
self.driver.quit()
41+
42+
@pytest.mark.parametrize("user_name,password", [
43+
("user1", "password1"),
44+
("user2", "password2"),
45+
])
46+
def test_shopping(self, user_name, password):
47+
# login
48+
username_et = self.find_element("userName")
49+
username_et.send_keys(user_name)
50+
password_et = self.find_element("password")
51+
password_et.send_keys(password)
52+
signin_bt = self.find_element("signIn")
53+
signin_bt.click()
54+
sleep(3)
55+
56+
# add 2 product to cart
57+
product_1 = self.find_element('product0')
58+
sleep(1)
59+
product_1.click()
60+
add_to_cart1 = self.find_element('add_to_cart_button')
61+
sleep(1)
62+
add_to_cart1.click()
63+
sleep(1)
64+
self.driver.press_keycode(4)
65+
66+
product_2 = self.find_element('product1')
67+
sleep(1)
68+
product_2.click()
69+
add_to_cart2 = self.find_element('add_to_cart_button')
70+
sleep(1)
71+
add_to_cart2.click()
72+
sleep(1)
73+
self.driver.press_keycode(4)
74+
75+
# click 1 product to wishlist
76+
product_3 = self.find_element('product2')
77+
sleep(1)
78+
product_3.click()
79+
like_button = self.find_element('like_button')
80+
sleep(1)
81+
like_button.click()
82+
sleep(1)
83+
self.driver.press_keycode(4)
84+
sleep(1)
85+
wishlist_tab = self.find_element('homeTab1')
86+
wishlist_tab.click()
87+
sleep(1)
88+
89+
cart_tab = self.find_element('homeTab2')
90+
cart_tab.click()
91+
checkout_bt = self.find_element('check_out_button')
92+
sleep(1)
93+
checkout_bt.click()
94+
95+
profile_tab = self.find_element('homeTab3')
96+
sleep(1)
97+
profile_tab.click()
98+
sign_out_bt = self.find_element('sign_out_button')
99+
sleep(1)
100+
sign_out_bt.click()
101+
self.driver.press_keycode(3)
102+
sleep(5)
103+
104+
def find_element(self, name):
105+
return self.driver.find_element(AppiumBy.ANDROID_UIAUTOMATOR,
106+
value='new UiSelector().resourceId("' + name + '")')
107+
108+
109+
if __name__ == '__main__':
110+
TestShopping.test_shopping()

0 commit comments

Comments
 (0)