Vinayak commited on
Commit
4a3720d
·
1 Parent(s): acdbb22

Add E2E test for puppet android app

Browse files

Adds github action workflow to run tests against trigger.
Adds test case to run tests against sauce labs.
Adds necessary boilerplate code to setup test execution.

.github/workflows/e2e_tests.yml ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: E2E Tests
2
+
3
+ on:
4
+ push:
5
+ branches: [ "main", "develop" ]
6
+ pull_request:
7
+ paths:
8
+ - "puppet/**"
9
+ branches: [ "main" ]
10
+ workflow_dispatch:
11
+ jobs:
12
+ build:
13
+ runs-on: ubuntu-latest
14
+ defaults:
15
+ run:
16
+ working-directory: e2_tests
17
+ env:
18
+ SAUCE_USERNAME : ${{ secrets.SAUCE_USERNAME }}
19
+ SAUCE_ACCESS_KEY : ${{ secrets.SAUCE_ACCESS_KEY }}
20
+ TEST_UUID : ${{ secrets.TEST_UUID }}
21
+ steps:
22
+ - uses: actions/checkout@v3
23
+ - name: Setup Python
24
+ - uses: actions/setup-python@v4
25
+ with:
26
+ python-version: '3.10'
27
+ cache: 'pip' # caching pip dependencies
28
+ - run: pip install -r requirements.txt
29
+ - run: python test_sauce_labs.py
e2e_tests/README.md ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Running E2E Tests
2
+
3
+ This serves as a framework to build regression tests for puppet android app.
4
+ Currently the test supports running the tests against the built android package in dev machine or in sauce labs.
5
+
6
+ Common code to enable/activate privacy setting for puppet app exists in the same file.
7
+ Which can be abstracted away in future to make it reusable across other test files.
8
+ This uses Appium to drive the android app and send instructions.
9
+
10
+ For SauceLabs test assumes the username, accesskey and UUID is available as environment variable.
11
+
12
+ By altering the device name, the tests can be run against an emulator or real android device in saucelabs.
13
+
14
+ For local machine, an appium server, android emulator and Java SDK is required.
15
+
16
+ `pip install -r requirements.txt`
17
+
18
+ `python test_sauce_labs.py`
e2e_tests/requirements.txt ADDED
@@ -0,0 +1 @@
 
 
1
+ Appium-Python-Client==2.11.1
e2e_tests/test_sauce_labs.py ADDED
@@ -0,0 +1,125 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Python/Pytest
2
+ from contextlib import contextmanager
3
+ import time
4
+ import unittest
5
+ import os
6
+
7
+ from appium import webdriver
8
+ from appium.webdriver.common.appiumby import AppiumBy
9
+ from selenium.webdriver.remote.webdriver import WebDriver
10
+
11
+ APPIUM_PORT = 4723
12
+ APPIUM_HOST = '127.0.0.1'
13
+
14
+ SAUCE_USERNAME = os.getenv("SAUCE_USERNAME")
15
+ SAUCE_ACCESS_KEY = os.getenv("SAUCE_ACCESS_KEY")
16
+ TEST_UUID = os.getenv("TEST_UUID", "")
17
+
18
+ def create_android_driver(sauce_labs = False):
19
+ capabilities = dict(
20
+ platformName='Android',
21
+ automationName='uiautomator2',
22
+ deviceName='Android',
23
+ appPackage='com.ttt246.puppet',
24
+ appActivity='.ChatterAct',
25
+ language='en',
26
+ locale='US'
27
+ )
28
+ capabilities["appium:app"] = "app-release-unsigned.apk"
29
+ capabilities["autoGrantPermissions"] = "true"
30
+ connection_url = f'http://{APPIUM_HOST}:{APPIUM_PORT}'
31
+ if sauce_labs:
32
+ capabilities['platformName'] = 'Android'
33
+ capabilities['appium:app'] = 'storage:filename=app-release-unsigned.apk'
34
+ capabilities['appium:deviceName'] = 'Android GoogleAPI Emulator'
35
+ capabilities['appium:deviceOrientation'] = 'portrait'
36
+ capabilities['appium:platformVersion'] = '13.0'
37
+ capabilities['appium:automationName'] = 'uiautomator2'
38
+ capabilities['appPackage'] = 'com.ttt246.puppet'
39
+ capabilities['appActivity'] ='.ChatterAct'
40
+ capabilities["appium:autoGrantPermissions"] = 'true'
41
+ capabilities['sauce:options'] = {}
42
+ capabilities['sauce:options']['username'] = SAUCE_USERNAME;
43
+ capabilities['sauce:options']['accessKey'] = SAUCE_ACCESS_KEY;
44
+ capabilities['sauce:options']['build'] = 'appium-build-HGNZD'
45
+ capabilities['sauce:options']['name'] = 'Automate Tests'
46
+ capabilities['appium:app'] = 'storage:filename=app-release-unsigned.apk'
47
+ capabilities['appium:deviceName'] = 'Android GoogleAPI Emulator'
48
+
49
+ connection_url = 'https://ondemand.us-west-1.saucelabs.com:443/wd/hub'
50
+
51
+ return webdriver.Remote(connection_url, capabilities)
52
+
53
+
54
+ @contextmanager
55
+ def android_driver(options):
56
+ # prefer this fixture if there is no need to customize driver options in tests
57
+ driver = create_android_driver(sauce_labs=True)
58
+ yield driver
59
+ driver.quit()
60
+
61
+ def save_server_settings(driver: WebDriver):
62
+ el8 = driver.find_element(by=AppiumBy.ID, value="com.ttt246.puppet:id/settingsButton")
63
+ el8.click()
64
+ el9 = driver.find_element(by=AppiumBy.ID, value="com.ttt246.puppet:id/serverUrlEditText")
65
+ el9.send_keys("https://posix4e-puppet.hf.space")
66
+ el10 = driver.find_element(by=AppiumBy.ID, value="com.ttt246.puppet:id/uuidEditText")
67
+ el10.send_keys("1608052e-b294-4a6f-a69f-e18c9bedf5c8")
68
+ el11 = driver.find_element(by=AppiumBy.ID, value="com.ttt246.puppet:id/saveButton")
69
+ el11.click()
70
+
71
+ def enable_privacy_settings(driver: WebDriver):
72
+ driver.find_element(by=AppiumBy.XPATH, value='//*[@text="puppet"]').click()
73
+ primary_checkbox = driver.find_element(by=AppiumBy.ID, value='android:id/switch_widget')
74
+
75
+ # Use Puppet button
76
+ if not primary_checkbox.get_attribute("checked") == "true":
77
+ primary_checkbox.click()
78
+ try:
79
+ driver.find_element(by=AppiumBy.XPATH, value="//*[@text='Allow']").click()
80
+ except Exception as e:
81
+ pass
82
+
83
+ # Puppet shortcut button
84
+ secondary_checkbox = driver.find_element(by=AppiumBy.ID, value='com.android.settings:id/switchWidget')
85
+ if not secondary_checkbox.get_attribute("checked") == "true":
86
+ secondary_checkbox.click()
87
+ try:
88
+ driver.find_element(by=AppiumBy.XPATH, value="//*[@text='Got it']").click()
89
+ except Exception as e:
90
+ pass
91
+
92
+ time.sleep(2)
93
+ driver.back()
94
+ time.sleep(2)
95
+ driver.back()
96
+
97
+ class TestAppium(unittest.TestCase):
98
+ def test_tab_4(self):
99
+ import time
100
+ # Usage of the context manager ensures the driver session is closed properly
101
+ # after the test completes. Otherwise, make sure to call `driver.quit()` on teardown.
102
+ with android_driver({}) as driver:
103
+ driver.implicitly_wait(10)
104
+
105
+ enable_privacy_settings(driver)
106
+
107
+ driver.activate_app("com.ttt246.puppet")
108
+ driver.wait_activity(".ChatterAct", 5)
109
+ time.sleep(2)
110
+
111
+ save_server_settings(driver)
112
+
113
+ el14 = driver.find_element(by=AppiumBy.XPATH, value='//*[@text="Tab 4"]')
114
+ el14.click()
115
+ el15 = driver.find_element(by=AppiumBy.XPATH, value="//android.widget.EditText[@hint='UID']")
116
+ el15.send_keys(TEST_UUID)
117
+ el16 = driver.find_element(by=AppiumBy.XPATH, value="//android.widget.EditText[@hint='Command']")
118
+ el16.send_keys("test")
119
+ el17 = driver.find_element(by=AppiumBy.XPATH, value='//*[@text="Submit"]')
120
+ el17.click()
121
+ time.sleep(5)
122
+
123
+
124
+ if __name__ == "__main__":
125
+ unittest.main()