├── .env
├── .github
├── pull_request_template.md
└── workflows
│ └── main.yml
├── .gitignore
├── .travis.yml
├── app.log
├── conftest.py
├── data
└── apps
│ ├── Android-NativeDemoApp-0.2.1.apk
│ ├── iOS-RealDevice-NativeDemoApp-0.2.1.ipa
│ └── iOS-Simulator-NativeDemoApp-0.2.1.app
│ ├── AppIcon20x20@2x.png
│ ├── AppIcon20x20@3x.png
│ ├── AppIcon29x29@2x.png
│ ├── AppIcon29x29@3x.png
│ ├── AppIcon40x40@2x.png
│ ├── AppIcon40x40@3x.png
│ ├── AppIcon60x60@2x.png
│ ├── AppIcon60x60@3x.png
│ ├── Assets.car
│ ├── Entypo.ttf
│ ├── EvilIcons.ttf
│ ├── Feather.ttf
│ ├── FontAwesome.ttf
│ ├── FontAwesome5_Brands.ttf
│ ├── FontAwesome5_Regular.ttf
│ ├── FontAwesome5_Solid.ttf
│ ├── Foundation.ttf
│ ├── Frameworks
│ ├── XCTest.framework
│ │ ├── Info.plist
│ │ ├── XCTest
│ │ ├── _CodeSignature
│ │ │ └── CodeResources
│ │ ├── en.lproj
│ │ │ └── InfoPlist.strings
│ │ └── version.plist
│ └── libXCTestBundleInject.dylib
│ ├── Info.plist
│ ├── Ionicons.ttf
│ ├── LaunchImage-1100-Portrait-2436h@3x.png
│ ├── LaunchImage-700-568h@2x.png
│ ├── LaunchImage-800-667h@2x.png
│ ├── LaunchImage-800-Portrait-736h@3x.png
│ ├── LaunchImage.png
│ ├── MaterialCommunityIcons.ttf
│ ├── MaterialIcons.ttf
│ ├── Octicons.ttf
│ ├── PkgInfo
│ ├── PlugIns
│ ├── wdioDemoAppTests.xctest.dSYM
│ │ └── Contents
│ │ │ ├── Info.plist
│ │ │ └── Resources
│ │ │ └── DWARF
│ │ │ └── wdioDemoAppTests
│ └── wdioDemoAppTests.xctest
│ │ ├── Info.plist
│ │ ├── _CodeSignature
│ │ └── CodeResources
│ │ └── wdioDemoAppTests
│ ├── SimpleLineIcons.ttf
│ ├── Zocial.ttf
│ ├── _CodeSignature
│ └── CodeResources
│ ├── assets
│ ├── js
│ │ └── assets
│ │ │ └── webdriverio.png
│ └── node_modules
│ │ ├── @tele2
│ │ └── react-native-select-input
│ │ │ └── src
│ │ │ └── icons
│ │ │ ├── arrowDown.png
│ │ │ └── arrowUp.png
│ │ ├── react-native-elements
│ │ └── src
│ │ │ └── rating
│ │ │ └── images
│ │ │ ├── bell.png
│ │ │ ├── heart.png
│ │ │ ├── rocket.png
│ │ │ └── star.png
│ │ └── react-navigation-stack
│ │ └── dist
│ │ └── views
│ │ └── assets
│ │ ├── back-icon-mask.png
│ │ ├── back-icon.png
│ │ ├── back-icon@2x.png
│ │ └── back-icon@3x.png
│ ├── main.jsbundle
│ └── wdioDemoApp
├── pytest.ini
├── readme.md
├── report
├── 6d01bfcc-98f1-4278-a4c5-6fc2b55772bb-result.json
├── assets
│ └── style.css
├── c5704f6f-6816-476a-83df-b5b8b491dee2-container.json
└── report.html
├── requirements.txt
├── runner
├── android
│ └── smoke_run.sh
└── ios
│ ├── smoke_run.sh
│ └── smoke_run_bitrise.sh
├── screenshots
└── test_home_2019-09-10_13-29-38.png
├── settings.py
├── src
├── helpers
│ ├── app.py
│ ├── appiumdriver.py
│ ├── business.py
│ └── constants.py
├── screens
│ ├── android
│ │ ├── base_screen.py
│ │ ├── home_screen.py
│ │ └── login_screen.py
│ └── ios
│ │ ├── base_screen.py
│ │ ├── home_screen.py
│ │ └── login_screen.py
└── spec
│ ├── android
│ ├── home_test.py
│ └── login_test.py
│ └── ios
│ ├── home_test.py
│ └── login_test.py
└── tasks.py
/.env:
--------------------------------------------------------------------------------
1 | SLACK_TOKEN=XXXXXXX/XXXXXXXXXXXXXX/XXXXXXXXXXXXXXXXXXXXXXXXXXXX
2 | UDID=XXXXXXXXXXXXXXXXXXXXXXXXXXXX
--------------------------------------------------------------------------------
/.github/pull_request_template.md:
--------------------------------------------------------------------------------
1 | # Merge checklist
2 | - [ ] TravisCI tests passed
3 | - [ ] Documentation
--------------------------------------------------------------------------------
/.github/workflows/main.yml:
--------------------------------------------------------------------------------
1 | on: push
2 | name: Lint Python
3 | jobs:
4 | lint:
5 | runs-on: ubuntu-latest
6 | steps:
7 | - uses: actions/checkout@v2
8 | - uses: cclauss/Find-Python-syntax-errors-action@master
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | app.log
2 | .DS_Store
3 | src/helpers/helpers_old.py
4 | src/helpers/helpers.py
5 | __pycache__/
6 | *.pyc
7 | .travis.yml
8 | screenshots/
9 | report/
10 | .idea/
11 | dump/
12 | .pytest_cache/
13 | venv/
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | sudo: required
2 | language: android
3 | jdk: oraclejdk8
4 | image: thyrlian/android-sdk
5 |
6 | android:
7 | components:
8 | - tools
9 | - platform-tools
10 | # - build-tools-29.0.0
11 | # - build-tools-28.0.2
12 | - build-tools-25.0.2
13 | - android-25
14 | # - android-28
15 | - extra-google-google_play_services
16 | - extra-google-m2repository
17 | - extra-android-support
18 | - extra-android-m2repository
19 | # - addon-google_apis-google-28
20 | # - sys-img-armeabi-v7a-android-28
21 | - add-on
22 | - extra
23 |
24 | before_install:
25 | - sudo apt-get update
26 | - sudo apt-get install -y make build-essential libssl-dev zlib1g-dev libbz2-dev libreadline-dev
27 | libsqlite3-dev wget curl llvm libncurses5-dev libncursesw5-dev xz-utils tk-dev
28 | - git clone https://github.com/pyenv/pyenv.git ~/.pyenv
29 | - echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bash_profile
30 | - echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bash_profile
31 | - echo 'eval "$(pyenv init -)"' >> ~/.bash_profile
32 | - git clone https://github.com/yyuu/pyenv-virtualenv.git ~/.pyenv/plugins/pyenv-virtualenv
33 | - echo 'eval "$(pyenv virtualenv-init -)"' >> ~/.bash_profile
34 | - source ~/.bash_profile
35 | - pyenv versions
36 | - pyenv install 3.6.1
37 | - pyenv virtualenv 3.6.1 undang
38 | - pyenv activate undang
39 | - pip install -r requirements.txt
40 | - curl -sL https://deb.nodesource.com/setup_9.x | sudo -E bash -
41 | - sudo apt-get install nodejs
42 | - sudo apt-get install build-essential
43 | - PATH=$PATH:$JAVA_HOME/bin
44 | - npm install appium
45 | - npm install appium-doctor
46 | - "./node_modules/.bin/appium-doctor"
47 | - "./node_modules/.bin/appium --log-level info > appium_log.txt &"
48 | - sdkmanager tools
49 | # - echo yes | sdkmanager "build-tools;25.0.2"
50 | # - echo yes | sdkmanager "platforms;android-25"
51 |
52 | before_script:
53 | - echo y | sdkmanager "system-images;android-25;google_apis;armeabi-v7a"
54 | - echo "no" | avdmanager --verbose create avd -n PF -k "system-images;android-25;google_apis;armeabi-v7a" -b google_apis/armeabi-v7a -f
55 | # -k "system-images;android-25;google_apis;armeabi-v7a" --abi "google_apis;armeabi-v7a" --tag google_apis --device "pixel" --name PF --force
56 | # - echo no | android create avd --force -n PF -t android-28 --abi armeabi-v7a
57 | - $ANDROID_HOME/emulator/emulator -avd PF -no-skin -no-audio -no-window &
58 | - android-wait-for-emulator
59 | - adb shell input keyevent 82 &
60 |
61 | script:
62 | - avd devices
63 | - "./gradlew assemble" # Build
64 | # - ./gradlew clean connectedCheck
65 | # - chmod +x ./gradlew
66 | # - ./gradlew connectedAndroidTest mergeAndroidReports --continue -PdisablePreDex --stacktrace
67 | - python3 -m pytest src/spec/* # Test
68 |
69 | after_script:
70 | - cat ./appium_log.txt # Check appium log
71 |
--------------------------------------------------------------------------------
/app.log:
--------------------------------------------------------------------------------
1 | 07/16/2020 12:09:02 PM - INFO: Configuring desired capabilities
2 | 07/16/2020 12:09:02 PM - INFO: Initiating Appium driver
3 |
--------------------------------------------------------------------------------
/conftest.py:
--------------------------------------------------------------------------------
1 | import logging
2 | import pytest
3 |
4 |
5 | @pytest.hookimpl
6 | def pytest_addoption(parser):
7 | parser.addoption('--app', action='store', default="ios", help="Choose App: ios or android")
8 | parser.addoption('--device', action='store', default="emulator", help="Choose Device: simulator / emulator / real "
9 | "device")
10 |
11 |
12 | @pytest.fixture(scope="session")
13 | def app(request):
14 | return request.config.getoption("--app")
15 |
16 |
17 | @pytest.fixture(scope="session")
18 | def device(request):
19 | return request.config.getoption("--device")
20 |
21 |
22 | @pytest.fixture(scope='session')
23 | def get_logger():
24 | logger = logging.getLogger(__name__)
25 | logger.setLevel(logging.DEBUG)
26 | ch = logging.FileHandler(r'app.log', mode='w')
27 | ch.setLevel(logging.DEBUG)
28 | formatter = logging.Formatter('%(asctime)s - %(levelname)s: %(message)s', '%m/%d/%Y %I:%M:%S %p')
29 | ch.setFormatter(formatter)
30 | logger.addHandler(ch)
31 | return logger
32 |
33 | # @pytest.fixture(scope='session', autouse=True)
34 | # def session_setup_teardown():
35 | # yield
36 | # notify_slack()
37 |
--------------------------------------------------------------------------------
/data/apps/Android-NativeDemoApp-0.2.1.apk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prashanth-sams/python-appium-framework/7b75bd44366758192a385acbec9a64ec987d3afe/data/apps/Android-NativeDemoApp-0.2.1.apk
--------------------------------------------------------------------------------
/data/apps/iOS-RealDevice-NativeDemoApp-0.2.1.ipa:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prashanth-sams/python-appium-framework/7b75bd44366758192a385acbec9a64ec987d3afe/data/apps/iOS-RealDevice-NativeDemoApp-0.2.1.ipa
--------------------------------------------------------------------------------
/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/AppIcon20x20@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prashanth-sams/python-appium-framework/7b75bd44366758192a385acbec9a64ec987d3afe/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/AppIcon20x20@2x.png
--------------------------------------------------------------------------------
/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/AppIcon20x20@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prashanth-sams/python-appium-framework/7b75bd44366758192a385acbec9a64ec987d3afe/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/AppIcon20x20@3x.png
--------------------------------------------------------------------------------
/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/AppIcon29x29@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prashanth-sams/python-appium-framework/7b75bd44366758192a385acbec9a64ec987d3afe/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/AppIcon29x29@2x.png
--------------------------------------------------------------------------------
/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/AppIcon29x29@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prashanth-sams/python-appium-framework/7b75bd44366758192a385acbec9a64ec987d3afe/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/AppIcon29x29@3x.png
--------------------------------------------------------------------------------
/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/AppIcon40x40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prashanth-sams/python-appium-framework/7b75bd44366758192a385acbec9a64ec987d3afe/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/AppIcon40x40@2x.png
--------------------------------------------------------------------------------
/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/AppIcon40x40@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prashanth-sams/python-appium-framework/7b75bd44366758192a385acbec9a64ec987d3afe/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/AppIcon40x40@3x.png
--------------------------------------------------------------------------------
/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/AppIcon60x60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prashanth-sams/python-appium-framework/7b75bd44366758192a385acbec9a64ec987d3afe/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/AppIcon60x60@2x.png
--------------------------------------------------------------------------------
/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/AppIcon60x60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prashanth-sams/python-appium-framework/7b75bd44366758192a385acbec9a64ec987d3afe/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/AppIcon60x60@3x.png
--------------------------------------------------------------------------------
/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/Assets.car:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prashanth-sams/python-appium-framework/7b75bd44366758192a385acbec9a64ec987d3afe/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/Assets.car
--------------------------------------------------------------------------------
/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/Entypo.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prashanth-sams/python-appium-framework/7b75bd44366758192a385acbec9a64ec987d3afe/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/Entypo.ttf
--------------------------------------------------------------------------------
/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/EvilIcons.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prashanth-sams/python-appium-framework/7b75bd44366758192a385acbec9a64ec987d3afe/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/EvilIcons.ttf
--------------------------------------------------------------------------------
/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/Feather.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prashanth-sams/python-appium-framework/7b75bd44366758192a385acbec9a64ec987d3afe/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/Feather.ttf
--------------------------------------------------------------------------------
/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/FontAwesome.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prashanth-sams/python-appium-framework/7b75bd44366758192a385acbec9a64ec987d3afe/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/FontAwesome.ttf
--------------------------------------------------------------------------------
/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/FontAwesome5_Brands.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prashanth-sams/python-appium-framework/7b75bd44366758192a385acbec9a64ec987d3afe/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/FontAwesome5_Brands.ttf
--------------------------------------------------------------------------------
/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/FontAwesome5_Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prashanth-sams/python-appium-framework/7b75bd44366758192a385acbec9a64ec987d3afe/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/FontAwesome5_Regular.ttf
--------------------------------------------------------------------------------
/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/FontAwesome5_Solid.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prashanth-sams/python-appium-framework/7b75bd44366758192a385acbec9a64ec987d3afe/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/FontAwesome5_Solid.ttf
--------------------------------------------------------------------------------
/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/Foundation.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prashanth-sams/python-appium-framework/7b75bd44366758192a385acbec9a64ec987d3afe/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/Foundation.ttf
--------------------------------------------------------------------------------
/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/Frameworks/XCTest.framework/Info.plist:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prashanth-sams/python-appium-framework/7b75bd44366758192a385acbec9a64ec987d3afe/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/Frameworks/XCTest.framework/Info.plist
--------------------------------------------------------------------------------
/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/Frameworks/XCTest.framework/XCTest:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prashanth-sams/python-appium-framework/7b75bd44366758192a385acbec9a64ec987d3afe/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/Frameworks/XCTest.framework/XCTest
--------------------------------------------------------------------------------
/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/Frameworks/XCTest.framework/_CodeSignature/CodeResources:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | files
6 |
7 | Headers/XCAbstractTest.h
8 |
9 | 4jnRu9kM4nMP+Xh3ikwmHuBDxsI=
10 |
11 | Headers/XCTActivity.h
12 |
13 | BVKd+CuVL/fMWVnojVTY7BZiXkc=
14 |
15 | Headers/XCTAttachment.h
16 |
17 | D+igalTdqMWvG/cB1056ns8u3B8=
18 |
19 | Headers/XCTAttachmentLifetime.h
20 |
21 | uBkx/rPKjZiieZXjaYSrZHfYrQc=
22 |
23 | Headers/XCTContext.h
24 |
25 | S2c/fkq5xnjLgsMY3mNIE7jPMFE=
26 |
27 | Headers/XCTDarwinNotificationExpectation.h
28 |
29 | T1bfewH+fYADesmaBVQWzTdVRjk=
30 |
31 | Headers/XCTKVOExpectation.h
32 |
33 | s28+hglUCU24y2eMlji4++ZVC+0=
34 |
35 | Headers/XCTNSNotificationExpectation.h
36 |
37 | ZC9t23DBiU7y/pJ116Zgt8q1/J4=
38 |
39 | Headers/XCTNSPredicateExpectation.h
40 |
41 | ZeWBK1Un0h29h5DRuqDXCiqCOnk=
42 |
43 | Headers/XCTWaiter.h
44 |
45 | 3xRcrUqW54PHl7VXGv1RNSfgZAg=
46 |
47 | Headers/XCTest.apinotes
48 |
49 | WqUywzmEAqoV6c0qeOnMA2dcIQc=
50 |
51 | Headers/XCTest.h
52 |
53 | vyHRJ5iIHDimvUMhPRtMJzhrlW4=
54 |
55 | Headers/XCTestAssertions.h
56 |
57 | TFhruscn++ANKgidq0O8+oRGZg0=
58 |
59 | Headers/XCTestAssertionsImpl.h
60 |
61 | FMlfpxJpHMUMoOhkV78DHSY1H74=
62 |
63 | Headers/XCTestCase+AsynchronousTesting.h
64 |
65 | dIWmXJMmBG4KZlskftye7w5BFSI=
66 |
67 | Headers/XCTestCase.h
68 |
69 | wj3AeIl6hv7IjEECC8+IYM1Mm2Q=
70 |
71 | Headers/XCTestCaseRun.h
72 |
73 | /XUqDHA/BFdQDUxQU8Ft5LXo/Ps=
74 |
75 | Headers/XCTestDefines.h
76 |
77 | po6ETUvux87Rma0YA5sp9vfGHSs=
78 |
79 | Headers/XCTestErrors.h
80 |
81 | +vO07iqBB7ZsrpEHPOAtvqTwUVc=
82 |
83 | Headers/XCTestExpectation.h
84 |
85 | Y/ssvPOSAIHfa/G1pVREFYwgDq8=
86 |
87 | Headers/XCTestLog.h
88 |
89 | 9BU/gwbaKcfn2L9dfo2dHRFN6Bc=
90 |
91 | Headers/XCTestObservation.h
92 |
93 | eYPPds+/sIm1g8tzzWEi74ngT8s=
94 |
95 | Headers/XCTestObservationCenter.h
96 |
97 | 5ySsNYFGF0ZFvLZnL7UTg1HNRR4=
98 |
99 | Headers/XCTestObserver.h
100 |
101 | DV3Cjdd1CAe6nYFEzmUrCtnzxQg=
102 |
103 | Headers/XCTestProbe.h
104 |
105 | fIVR0xRsxMAabrJmeGX3hPDwL0Y=
106 |
107 | Headers/XCTestRun.h
108 |
109 | 7GVNxTeghh0aBxY/Gvb+j2VTkqQ=
110 |
111 | Headers/XCTestSuite.h
112 |
113 | eRc+OVrMoZSKfP/hWkP9044Xkwo=
114 |
115 | Headers/XCTestSuiteRun.h
116 |
117 | OX+g52bOAnhjLVDKkweTKM8jTHQ=
118 |
119 | Headers/XCUIApplication.h
120 |
121 | 3xPGyAQELvSZZ4RHMwhQEnlzFhg=
122 |
123 | Headers/XCUICoordinate.h
124 |
125 | ISpzcCIN+bNtcvHSlqKq3H0dHAA=
126 |
127 | Headers/XCUIDevice.h
128 |
129 | 6pJZzs6nb9PxIhPZMSzM3Pnoyyk=
130 |
131 | Headers/XCUIElement.h
132 |
133 | 25uxff90oirJoEGqmcoId+OQAJU=
134 |
135 | Headers/XCUIElementAttributes.h
136 |
137 | 8ihGn99tX4C4PPRNW4qUqlS9tBo=
138 |
139 | Headers/XCUIElementQuery.h
140 |
141 | C3ZXTnkZIFu38bImb5YnKX8ME3s=
142 |
143 | Headers/XCUIElementTypeQueryProvider.h
144 |
145 | RByqnqCJz+rOh+n5b6A0LWE4ipY=
146 |
147 | Headers/XCUIElementTypes.h
148 |
149 | rS+FtIJ/fnc0UIdAg5Fupx0KuVc=
150 |
151 | Headers/XCUIKeyboardKeys.h
152 |
153 | iM5NitaH7AFOmYTcSm86X0OTpSw=
154 |
155 | Headers/XCUIRemote.h
156 |
157 | +rbCM60bDizOcqH+NaoTiCwtEH4=
158 |
159 | Headers/XCUIScreen.h
160 |
161 | DBqshlCvI4VeOu1t7slE1L12Akw=
162 |
163 | Headers/XCUIScreenshot.h
164 |
165 | WRAFpS5fsJOjpa68uJDYY7QcwzQ=
166 |
167 | Headers/XCUIScreenshotProviding.h
168 |
169 | qghz8l697gauRG1WZGkXCsisS40=
170 |
171 | Headers/XCUISiriService.h
172 |
173 | NtIeUU61kDhd8LGgBr1FjKXe6JQ=
174 |
175 | Info.plist
176 |
177 | DQ4GPJ7FuM6H+FaCC/2wxhPSGCQ=
178 |
179 | Modules/module.modulemap
180 |
181 | ha0qqLvU0UdkLu07qH5tE4agQV4=
182 |
183 | en.lproj/InfoPlist.strings
184 |
185 | hash
186 |
187 | TuBj57ZP6zBqcL9HttO2Rucaw9E=
188 |
189 | optional
190 |
191 |
192 | version.plist
193 |
194 | P6P66kW7+LvLIo4WHjXGltpT8CA=
195 |
196 |
197 | files2
198 |
199 | Headers/XCAbstractTest.h
200 |
201 | hash
202 |
203 | 4jnRu9kM4nMP+Xh3ikwmHuBDxsI=
204 |
205 | hash2
206 |
207 | IFgW59C1Ktqp4LtLT30sw91amGbNOGweE+JfCOD3+Zg=
208 |
209 |
210 | Headers/XCTActivity.h
211 |
212 | hash
213 |
214 | BVKd+CuVL/fMWVnojVTY7BZiXkc=
215 |
216 | hash2
217 |
218 | rRcgcNhfkv8++PLGoc2+V7RKA+20od2gktcAZnNphso=
219 |
220 |
221 | Headers/XCTAttachment.h
222 |
223 | hash
224 |
225 | D+igalTdqMWvG/cB1056ns8u3B8=
226 |
227 | hash2
228 |
229 | 5aviQX7pgXyeS3UISWFOjiiUf8kPCzFtPNnk08B2rrQ=
230 |
231 |
232 | Headers/XCTAttachmentLifetime.h
233 |
234 | hash
235 |
236 | uBkx/rPKjZiieZXjaYSrZHfYrQc=
237 |
238 | hash2
239 |
240 | yrLG05PHjYkx013jrhQuHeuuP2sz3+LqbAIRN/0Mqc4=
241 |
242 |
243 | Headers/XCTContext.h
244 |
245 | hash
246 |
247 | S2c/fkq5xnjLgsMY3mNIE7jPMFE=
248 |
249 | hash2
250 |
251 | aKMqn4OBmb2Fg3/8sTMLXW2eHWiyWP3bQkSzTnvrwmQ=
252 |
253 |
254 | Headers/XCTDarwinNotificationExpectation.h
255 |
256 | hash
257 |
258 | T1bfewH+fYADesmaBVQWzTdVRjk=
259 |
260 | hash2
261 |
262 | yghcN+Vtx2KfRi9uMiorSiMSUWkgipo2aBxjXGpindM=
263 |
264 |
265 | Headers/XCTKVOExpectation.h
266 |
267 | hash
268 |
269 | s28+hglUCU24y2eMlji4++ZVC+0=
270 |
271 | hash2
272 |
273 | s24Kr8S1fbS62TmPjWUVYBWo7l0mxOge/yAw3RVvRCQ=
274 |
275 |
276 | Headers/XCTNSNotificationExpectation.h
277 |
278 | hash
279 |
280 | ZC9t23DBiU7y/pJ116Zgt8q1/J4=
281 |
282 | hash2
283 |
284 | vHwq0rw8c1B93uSPcxyrdcpNF6gp5UqVvnMHKFPMSMg=
285 |
286 |
287 | Headers/XCTNSPredicateExpectation.h
288 |
289 | hash
290 |
291 | ZeWBK1Un0h29h5DRuqDXCiqCOnk=
292 |
293 | hash2
294 |
295 | S1UvUDqqEddmWd/HrxA/x6Hc5VP0fYA6PWhhbAX9PzY=
296 |
297 |
298 | Headers/XCTWaiter.h
299 |
300 | hash
301 |
302 | 3xRcrUqW54PHl7VXGv1RNSfgZAg=
303 |
304 | hash2
305 |
306 | mA5vx6/QQ25gHCNLjo9Y0eX1khy7s52IB7yacIGlrNk=
307 |
308 |
309 | Headers/XCTest.apinotes
310 |
311 | hash
312 |
313 | WqUywzmEAqoV6c0qeOnMA2dcIQc=
314 |
315 | hash2
316 |
317 | k+5JrEIKeIUahHN4rMRX6ihL13259MqcP597ms2vgMs=
318 |
319 |
320 | Headers/XCTest.h
321 |
322 | hash
323 |
324 | vyHRJ5iIHDimvUMhPRtMJzhrlW4=
325 |
326 | hash2
327 |
328 | vq64eNbcQBW4F9zCLXsPBM4vawf51Eq6PcVMcSyxLYI=
329 |
330 |
331 | Headers/XCTestAssertions.h
332 |
333 | hash
334 |
335 | TFhruscn++ANKgidq0O8+oRGZg0=
336 |
337 | hash2
338 |
339 | HNwN4r4tVDYAyxvEdGWpbCOzE9tjFMwivSpf/OMiSA0=
340 |
341 |
342 | Headers/XCTestAssertionsImpl.h
343 |
344 | hash
345 |
346 | FMlfpxJpHMUMoOhkV78DHSY1H74=
347 |
348 | hash2
349 |
350 | HR9g/DQVSYIlmIjN9aQo9QONQPkTY+7GRuFBie/i2so=
351 |
352 |
353 | Headers/XCTestCase+AsynchronousTesting.h
354 |
355 | hash
356 |
357 | dIWmXJMmBG4KZlskftye7w5BFSI=
358 |
359 | hash2
360 |
361 | zLn+sqbu8TwZu3fllS4K4kPFcGnfr8jhG5UWuQteqyI=
362 |
363 |
364 | Headers/XCTestCase.h
365 |
366 | hash
367 |
368 | wj3AeIl6hv7IjEECC8+IYM1Mm2Q=
369 |
370 | hash2
371 |
372 | grTesKyxgSO20bny3hiyO0ISXvlgcdenyXkWGIGjQFQ=
373 |
374 |
375 | Headers/XCTestCaseRun.h
376 |
377 | hash
378 |
379 | /XUqDHA/BFdQDUxQU8Ft5LXo/Ps=
380 |
381 | hash2
382 |
383 | jEzXeXeFAbT7xbfbqjlf4yF+lZvOKKw9u0dhT8Lzpe4=
384 |
385 |
386 | Headers/XCTestDefines.h
387 |
388 | hash
389 |
390 | po6ETUvux87Rma0YA5sp9vfGHSs=
391 |
392 | hash2
393 |
394 | XEUB26q3NNiOejd2zU8pAaf6LXWLdjEN4SgBi/oEHfU=
395 |
396 |
397 | Headers/XCTestErrors.h
398 |
399 | hash
400 |
401 | +vO07iqBB7ZsrpEHPOAtvqTwUVc=
402 |
403 | hash2
404 |
405 | hRldg6Kd690zh5Kxqa/je1cM/QAdhCdHnhSex8B/qQQ=
406 |
407 |
408 | Headers/XCTestExpectation.h
409 |
410 | hash
411 |
412 | Y/ssvPOSAIHfa/G1pVREFYwgDq8=
413 |
414 | hash2
415 |
416 | bzHkvrq2f+1FFP3qie5fF78p6scQOnD/r7WYoDW764A=
417 |
418 |
419 | Headers/XCTestLog.h
420 |
421 | hash
422 |
423 | 9BU/gwbaKcfn2L9dfo2dHRFN6Bc=
424 |
425 | hash2
426 |
427 | Tu+6JYZZzftcXmUWH11IO9/jXCXi6QPeWDrL6izup6s=
428 |
429 |
430 | Headers/XCTestObservation.h
431 |
432 | hash
433 |
434 | eYPPds+/sIm1g8tzzWEi74ngT8s=
435 |
436 | hash2
437 |
438 | DlaZPljnXduHBIxVFsQHWivHsQV6+QqtkPm3wqcNC9c=
439 |
440 |
441 | Headers/XCTestObservationCenter.h
442 |
443 | hash
444 |
445 | 5ySsNYFGF0ZFvLZnL7UTg1HNRR4=
446 |
447 | hash2
448 |
449 | d+hY4S23zmWO8E2YIrh4biGe9oQWCfD497a+oVk2+yY=
450 |
451 |
452 | Headers/XCTestObserver.h
453 |
454 | hash
455 |
456 | DV3Cjdd1CAe6nYFEzmUrCtnzxQg=
457 |
458 | hash2
459 |
460 | 7CTdhCJbuEzQNSyp3exgcCn6JnIRjBwpUcOKmiddBtU=
461 |
462 |
463 | Headers/XCTestProbe.h
464 |
465 | hash
466 |
467 | fIVR0xRsxMAabrJmeGX3hPDwL0Y=
468 |
469 | hash2
470 |
471 | FKXb32Ennc+6f3SkuVdo8bBNcIIWwryV5u5FmQYN8Fc=
472 |
473 |
474 | Headers/XCTestRun.h
475 |
476 | hash
477 |
478 | 7GVNxTeghh0aBxY/Gvb+j2VTkqQ=
479 |
480 | hash2
481 |
482 | bSeEEos9toHX4ZeMGeRYdv1KXdCziExa2r95Y6Qcem8=
483 |
484 |
485 | Headers/XCTestSuite.h
486 |
487 | hash
488 |
489 | eRc+OVrMoZSKfP/hWkP9044Xkwo=
490 |
491 | hash2
492 |
493 | L7lrx0/vT/6C441YiHqyBo8c41P7nh8AVfj2Ju9MWF0=
494 |
495 |
496 | Headers/XCTestSuiteRun.h
497 |
498 | hash
499 |
500 | OX+g52bOAnhjLVDKkweTKM8jTHQ=
501 |
502 | hash2
503 |
504 | QDxhlFfxAJEcudV29W9M96FJW5LQiR0yqdUHzkjMuA0=
505 |
506 |
507 | Headers/XCUIApplication.h
508 |
509 | hash
510 |
511 | 3xPGyAQELvSZZ4RHMwhQEnlzFhg=
512 |
513 | hash2
514 |
515 | c5JhLgu1HF3BRKMZa+lW3Uv/rhC85w7hROiHmgBDw8k=
516 |
517 |
518 | Headers/XCUICoordinate.h
519 |
520 | hash
521 |
522 | ISpzcCIN+bNtcvHSlqKq3H0dHAA=
523 |
524 | hash2
525 |
526 | WqIHIIX29PruSt0Ux3ajf2d2Ya6W7ES85APt7RfZEUQ=
527 |
528 |
529 | Headers/XCUIDevice.h
530 |
531 | hash
532 |
533 | 6pJZzs6nb9PxIhPZMSzM3Pnoyyk=
534 |
535 | hash2
536 |
537 | a332EuTW+1XyYOs10oV/xXmV18ua86gJqI6rQ/QIzJE=
538 |
539 |
540 | Headers/XCUIElement.h
541 |
542 | hash
543 |
544 | 25uxff90oirJoEGqmcoId+OQAJU=
545 |
546 | hash2
547 |
548 | tcQVVPrLnGHtpuOYH54AchAIAxphDf4BcsEKEIh9CVU=
549 |
550 |
551 | Headers/XCUIElementAttributes.h
552 |
553 | hash
554 |
555 | 8ihGn99tX4C4PPRNW4qUqlS9tBo=
556 |
557 | hash2
558 |
559 | /RERxiLo8BzHBf5biK7xsVJnDB73TOHeOH72FBuhMTo=
560 |
561 |
562 | Headers/XCUIElementQuery.h
563 |
564 | hash
565 |
566 | C3ZXTnkZIFu38bImb5YnKX8ME3s=
567 |
568 | hash2
569 |
570 | LF3E68WtedEEM/IFD3q/tOZ3q0JtUQQhOK4XkamNjNM=
571 |
572 |
573 | Headers/XCUIElementTypeQueryProvider.h
574 |
575 | hash
576 |
577 | RByqnqCJz+rOh+n5b6A0LWE4ipY=
578 |
579 | hash2
580 |
581 | KPNzI8l6orkq7Lw9Lptey1l4nsXuyg/c9kYgH2/O5x0=
582 |
583 |
584 | Headers/XCUIElementTypes.h
585 |
586 | hash
587 |
588 | rS+FtIJ/fnc0UIdAg5Fupx0KuVc=
589 |
590 | hash2
591 |
592 | PUsaHf1pPvtkPng1Gk8jnyBg64It8wcfcNQK5lbNMs4=
593 |
594 |
595 | Headers/XCUIKeyboardKeys.h
596 |
597 | hash
598 |
599 | iM5NitaH7AFOmYTcSm86X0OTpSw=
600 |
601 | hash2
602 |
603 | MbFj4xHxsP2eF3L+IKG6cETqjvOpZFLq0ztIDCdeyt8=
604 |
605 |
606 | Headers/XCUIRemote.h
607 |
608 | hash
609 |
610 | +rbCM60bDizOcqH+NaoTiCwtEH4=
611 |
612 | hash2
613 |
614 | w7DXRAekwdX2XMbVLAxEj/q2faSvgp1LMbKGZDcUznE=
615 |
616 |
617 | Headers/XCUIScreen.h
618 |
619 | hash
620 |
621 | DBqshlCvI4VeOu1t7slE1L12Akw=
622 |
623 | hash2
624 |
625 | 45JwTQ4UtWVT2wvzdq2QOl8rBZ9Wxq9ubBB2vGvgBKc=
626 |
627 |
628 | Headers/XCUIScreenshot.h
629 |
630 | hash
631 |
632 | WRAFpS5fsJOjpa68uJDYY7QcwzQ=
633 |
634 | hash2
635 |
636 | F2tCZijPx0hU+7CIdW0fMZK4cwKbgFYiI9LKYINt5sU=
637 |
638 |
639 | Headers/XCUIScreenshotProviding.h
640 |
641 | hash
642 |
643 | qghz8l697gauRG1WZGkXCsisS40=
644 |
645 | hash2
646 |
647 | s35VI6Lzy6LUDsIoANQTenLSsJeaPXvonWElqk8cJbM=
648 |
649 |
650 | Headers/XCUISiriService.h
651 |
652 | hash
653 |
654 | NtIeUU61kDhd8LGgBr1FjKXe6JQ=
655 |
656 | hash2
657 |
658 | 6JTR/e2zA54rVmT1cblklOkL8LFXaYg81YGhVhoagsw=
659 |
660 |
661 | Modules/module.modulemap
662 |
663 | hash
664 |
665 | ha0qqLvU0UdkLu07qH5tE4agQV4=
666 |
667 | hash2
668 |
669 | w5Zd8voFpYyDVfx4t9/bCAZAs1kTrhmGSzTXQMiBd/c=
670 |
671 |
672 | en.lproj/InfoPlist.strings
673 |
674 | hash
675 |
676 | TuBj57ZP6zBqcL9HttO2Rucaw9E=
677 |
678 | hash2
679 |
680 | 89RGkjZaKuewYnjpzwhIswhqfrU8+pcEXqM/DHVrUmo=
681 |
682 | optional
683 |
684 |
685 | version.plist
686 |
687 | hash
688 |
689 | P6P66kW7+LvLIo4WHjXGltpT8CA=
690 |
691 | hash2
692 |
693 | 2BV684CZjHtMZHxSiwC5qc/DGXv9WIOWUc9dEU/Q1pw=
694 |
695 |
696 |
697 | rules
698 |
699 | ^
700 |
701 | ^.*\.lproj/
702 |
703 | optional
704 |
705 | weight
706 | 1000
707 |
708 | ^.*\.lproj/locversion.plist$
709 |
710 | omit
711 |
712 | weight
713 | 1100
714 |
715 | ^Base\.lproj/
716 |
717 | weight
718 | 1010
719 |
720 | ^version.plist$
721 |
722 |
723 | rules2
724 |
725 | .*\.dSYM($|/)
726 |
727 | weight
728 | 11
729 |
730 | ^
731 |
732 | weight
733 | 20
734 |
735 | ^(.*/)?\.DS_Store$
736 |
737 | omit
738 |
739 | weight
740 | 2000
741 |
742 | ^(Frameworks|SharedFrameworks|PlugIns|Plug-ins|XPCServices|Helpers|MacOS|Library/(Automator|Spotlight|LoginItems))/
743 |
744 | nested
745 |
746 | weight
747 | 10
748 |
749 | ^.*
750 |
751 | ^.*\.lproj/
752 |
753 | optional
754 |
755 | weight
756 | 1000
757 |
758 | ^.*\.lproj/locversion.plist$
759 |
760 | omit
761 |
762 | weight
763 | 1100
764 |
765 | ^Base\.lproj/
766 |
767 | weight
768 | 1010
769 |
770 | ^Info\.plist$
771 |
772 | omit
773 |
774 | weight
775 | 20
776 |
777 | ^PkgInfo$
778 |
779 | omit
780 |
781 | weight
782 | 20
783 |
784 | ^[^/]+$
785 |
786 | nested
787 |
788 | weight
789 | 10
790 |
791 | ^embedded\.provisionprofile$
792 |
793 | weight
794 | 20
795 |
796 | ^version\.plist$
797 |
798 | weight
799 | 20
800 |
801 |
802 |
803 |
804 |
--------------------------------------------------------------------------------
/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/Frameworks/XCTest.framework/en.lproj/InfoPlist.strings:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prashanth-sams/python-appium-framework/7b75bd44366758192a385acbec9a64ec987d3afe/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/Frameworks/XCTest.framework/en.lproj/InfoPlist.strings
--------------------------------------------------------------------------------
/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/Frameworks/XCTest.framework/version.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | BuildAliasOf
6 | XCTest
7 | BuildVersion
8 | 1
9 | CFBundleShortVersionString
10 | 1.0
11 | CFBundleVersion
12 | 14460.20
13 | ProjectName
14 | XCTest_Sim
15 | SourceVersion
16 | 14460020000000000
17 |
18 |
19 |
--------------------------------------------------------------------------------
/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/Frameworks/libXCTestBundleInject.dylib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prashanth-sams/python-appium-framework/7b75bd44366758192a385acbec9a64ec987d3afe/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/Frameworks/libXCTestBundleInject.dylib
--------------------------------------------------------------------------------
/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/Info.plist:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prashanth-sams/python-appium-framework/7b75bd44366758192a385acbec9a64ec987d3afe/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/Info.plist
--------------------------------------------------------------------------------
/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/Ionicons.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prashanth-sams/python-appium-framework/7b75bd44366758192a385acbec9a64ec987d3afe/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/Ionicons.ttf
--------------------------------------------------------------------------------
/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/LaunchImage-1100-Portrait-2436h@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prashanth-sams/python-appium-framework/7b75bd44366758192a385acbec9a64ec987d3afe/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/LaunchImage-1100-Portrait-2436h@3x.png
--------------------------------------------------------------------------------
/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/LaunchImage-700-568h@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prashanth-sams/python-appium-framework/7b75bd44366758192a385acbec9a64ec987d3afe/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/LaunchImage-700-568h@2x.png
--------------------------------------------------------------------------------
/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/LaunchImage-800-667h@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prashanth-sams/python-appium-framework/7b75bd44366758192a385acbec9a64ec987d3afe/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/LaunchImage-800-667h@2x.png
--------------------------------------------------------------------------------
/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/LaunchImage-800-Portrait-736h@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prashanth-sams/python-appium-framework/7b75bd44366758192a385acbec9a64ec987d3afe/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/LaunchImage-800-Portrait-736h@3x.png
--------------------------------------------------------------------------------
/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/LaunchImage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prashanth-sams/python-appium-framework/7b75bd44366758192a385acbec9a64ec987d3afe/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/LaunchImage.png
--------------------------------------------------------------------------------
/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/MaterialCommunityIcons.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prashanth-sams/python-appium-framework/7b75bd44366758192a385acbec9a64ec987d3afe/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/MaterialCommunityIcons.ttf
--------------------------------------------------------------------------------
/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/MaterialIcons.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prashanth-sams/python-appium-framework/7b75bd44366758192a385acbec9a64ec987d3afe/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/MaterialIcons.ttf
--------------------------------------------------------------------------------
/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/Octicons.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prashanth-sams/python-appium-framework/7b75bd44366758192a385acbec9a64ec987d3afe/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/Octicons.ttf
--------------------------------------------------------------------------------
/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/PkgInfo:
--------------------------------------------------------------------------------
1 | APPL????
--------------------------------------------------------------------------------
/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/PlugIns/wdioDemoAppTests.xctest.dSYM/Contents/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | English
7 | CFBundleIdentifier
8 | com.apple.xcode.dsym.org.reactjs.native.example.wdioDemoAppTests
9 | CFBundleInfoDictionaryVersion
10 | 6.0
11 | CFBundlePackageType
12 | dSYM
13 | CFBundleSignature
14 | ????
15 | CFBundleShortVersionString
16 | 0.2.1
17 | CFBundleVersion
18 | 2
19 |
20 |
21 |
--------------------------------------------------------------------------------
/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/PlugIns/wdioDemoAppTests.xctest.dSYM/Contents/Resources/DWARF/wdioDemoAppTests:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prashanth-sams/python-appium-framework/7b75bd44366758192a385acbec9a64ec987d3afe/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/PlugIns/wdioDemoAppTests.xctest.dSYM/Contents/Resources/DWARF/wdioDemoAppTests
--------------------------------------------------------------------------------
/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/PlugIns/wdioDemoAppTests.xctest/Info.plist:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prashanth-sams/python-appium-framework/7b75bd44366758192a385acbec9a64ec987d3afe/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/PlugIns/wdioDemoAppTests.xctest/Info.plist
--------------------------------------------------------------------------------
/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/PlugIns/wdioDemoAppTests.xctest/_CodeSignature/CodeResources:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | files
6 |
7 | Info.plist
8 |
9 | +hxJp3KTJhYFaxpSb0nRb6xol60=
10 |
11 |
12 | files2
13 |
14 | rules
15 |
16 | ^.*
17 |
18 | ^.*\.lproj/
19 |
20 | optional
21 |
22 | weight
23 | 1000
24 |
25 | ^.*\.lproj/locversion.plist$
26 |
27 | omit
28 |
29 | weight
30 | 1100
31 |
32 | ^Base\.lproj/
33 |
34 | weight
35 | 1010
36 |
37 | ^version.plist$
38 |
39 |
40 | rules2
41 |
42 | .*\.dSYM($|/)
43 |
44 | weight
45 | 11
46 |
47 | ^(.*/)?\.DS_Store$
48 |
49 | omit
50 |
51 | weight
52 | 2000
53 |
54 | ^.*
55 |
56 | ^.*\.lproj/
57 |
58 | optional
59 |
60 | weight
61 | 1000
62 |
63 | ^.*\.lproj/locversion.plist$
64 |
65 | omit
66 |
67 | weight
68 | 1100
69 |
70 | ^Base\.lproj/
71 |
72 | weight
73 | 1010
74 |
75 | ^Info\.plist$
76 |
77 | omit
78 |
79 | weight
80 | 20
81 |
82 | ^PkgInfo$
83 |
84 | omit
85 |
86 | weight
87 | 20
88 |
89 | ^embedded\.provisionprofile$
90 |
91 | weight
92 | 20
93 |
94 | ^version\.plist$
95 |
96 | weight
97 | 20
98 |
99 |
100 |
101 |
102 |
--------------------------------------------------------------------------------
/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/PlugIns/wdioDemoAppTests.xctest/wdioDemoAppTests:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prashanth-sams/python-appium-framework/7b75bd44366758192a385acbec9a64ec987d3afe/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/PlugIns/wdioDemoAppTests.xctest/wdioDemoAppTests
--------------------------------------------------------------------------------
/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/SimpleLineIcons.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prashanth-sams/python-appium-framework/7b75bd44366758192a385acbec9a64ec987d3afe/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/SimpleLineIcons.ttf
--------------------------------------------------------------------------------
/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/Zocial.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prashanth-sams/python-appium-framework/7b75bd44366758192a385acbec9a64ec987d3afe/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/Zocial.ttf
--------------------------------------------------------------------------------
/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/_CodeSignature/CodeResources:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | files
6 |
7 | AppIcon20x20@2x.png
8 |
9 | cQA2D7311Y5BS+yRjqXaoMTLGsE=
10 |
11 | AppIcon20x20@3x.png
12 |
13 | x0oQEZHvnDK31K5WuHtIqORHB8M=
14 |
15 | AppIcon29x29@2x.png
16 |
17 | 7I1dHNemalKrg/gMTiFwgwcXdsM=
18 |
19 | AppIcon29x29@3x.png
20 |
21 | w5oSziIFTapWAd2hVLfLHW7AjS4=
22 |
23 | AppIcon40x40@2x.png
24 |
25 | yd8J3m2ix7thyDKAybUzHVeebkY=
26 |
27 | AppIcon40x40@3x.png
28 |
29 | A8iXBEunjDTpgCglx+B0lu/ZW0Q=
30 |
31 | AppIcon60x60@2x.png
32 |
33 | A8iXBEunjDTpgCglx+B0lu/ZW0Q=
34 |
35 | AppIcon60x60@3x.png
36 |
37 | +uzoK4t4OJvCZfnnvi1OSqbGbDQ=
38 |
39 | Assets.car
40 |
41 | fFo5EUmn9fwj5tzxyT6C8FZq3vQ=
42 |
43 | Entypo.ttf
44 |
45 | R4cKZ91Qhxdl95nKqX2ochnuR8U=
46 |
47 | EvilIcons.ttf
48 |
49 | kdN36jz0dJCyVsLtCBcEp9q9rgw=
50 |
51 | Feather.ttf
52 |
53 | N8tVG0ETiQxSP0aeapsrKcTEm+Q=
54 |
55 | FontAwesome.ttf
56 |
57 | E7HqtlqYPHpzvHmXxHnWaUP3xss=
58 |
59 | FontAwesome5_Brands.ttf
60 |
61 | GeMCdg454lpfjZDWzQFk72zXT4w=
62 |
63 | FontAwesome5_Regular.ttf
64 |
65 | wUAIWDOjir7Gt9+Z1Mysk+smYDE=
66 |
67 | FontAwesome5_Solid.ttf
68 |
69 | xEWGSpZGlI4Nf/RJMK1zLuYUJ9g=
70 |
71 | Foundation.ttf
72 |
73 | SyvObHkkk6SlcWtv7C2+/olJLD8=
74 |
75 | Info.plist
76 |
77 | 9+Cdw1moi4MQsz29li0fMthH0VI=
78 |
79 | Ionicons.ttf
80 |
81 | mRu3+slwnNWNo3kBdw79RwPFQu0=
82 |
83 | LaunchImage-1100-Portrait-2436h@3x.png
84 |
85 | WVMhrESCCLI1t9yIOtrcuL+3Xxw=
86 |
87 | LaunchImage-700-568h@2x.png
88 |
89 | EWkGx/uPO2x11IQOfOPBNRFujc8=
90 |
91 | LaunchImage-800-667h@2x.png
92 |
93 | GohLdllr7BPHrWsF1KypmMzdKUw=
94 |
95 | LaunchImage-800-Portrait-736h@3x.png
96 |
97 | wIAJDjWk3HIwS+XL2l8819swQPE=
98 |
99 | LaunchImage.png
100 |
101 | 8w6cSczMaWkzN7+6DFpjZ1WZTWQ=
102 |
103 | MaterialCommunityIcons.ttf
104 |
105 | S1x3dOYog1mECtkRU/Ko2+92DD8=
106 |
107 | MaterialIcons.ttf
108 |
109 | /AXeMSNOAJD33cKM4bI69AJssdo=
110 |
111 | Octicons.ttf
112 |
113 | o/QP7s8JqAqYbxLVfGRtK0Wa+so=
114 |
115 | PkgInfo
116 |
117 | n57qDP4tZfLD1rCS43W0B4LQjzE=
118 |
119 | SimpleLineIcons.ttf
120 |
121 | n/uBpaEREuKS8swyPphIa61ZdZk=
122 |
123 | Zocial.ttf
124 |
125 | C9pZx7zT05J94EfgkYdaRCi/0as=
126 |
127 | assets/js/assets/webdriverio.png
128 |
129 | bzB5QCc/0qI/v7xgSfSg+bZBY6E=
130 |
131 | assets/node_modules/@tele2/react-native-select-input/src/icons/arrowDown.png
132 |
133 | EYQ62FQkMWvWIjm4HdYHdmoVNSU=
134 |
135 | assets/node_modules/@tele2/react-native-select-input/src/icons/arrowUp.png
136 |
137 | 10I7Y4F+kHEkxHvKSNQwjAlHeTM=
138 |
139 | assets/node_modules/react-native-elements/src/rating/images/bell.png
140 |
141 | mRk2D6wOdyusOvkEInbyL3K/E6k=
142 |
143 | assets/node_modules/react-native-elements/src/rating/images/heart.png
144 |
145 | rhZVvqRdTKoU0IrsdqQezFd0zb8=
146 |
147 | assets/node_modules/react-native-elements/src/rating/images/rocket.png
148 |
149 | mqOYKD+48iI8i2r6/LHKVlm0RGw=
150 |
151 | assets/node_modules/react-native-elements/src/rating/images/star.png
152 |
153 | XPFaCu1j/HeeE7zoK38ulP635qc=
154 |
155 | assets/node_modules/react-navigation-stack/dist/views/assets/back-icon-mask.png
156 |
157 | twCElRF9b860vkYvLPGRVtwtBcA=
158 |
159 | assets/node_modules/react-navigation-stack/dist/views/assets/back-icon.png
160 |
161 | keLOi1inJdXs0IRSKnXqyhW57Aw=
162 |
163 | assets/node_modules/react-navigation-stack/dist/views/assets/back-icon@2x.png
164 |
165 | rSvG8m4uPMSItIcsIF+N2tDJD8U=
166 |
167 | assets/node_modules/react-navigation-stack/dist/views/assets/back-icon@3x.png
168 |
169 | 8kFG8Vv7Hfrw4yVcFrhUhbHieBA=
170 |
171 | main.jsbundle
172 |
173 | ncuRxpKp81bWfMSflTw2td5B/e4=
174 |
175 |
176 | files2
177 |
178 | AppIcon20x20@2x.png
179 |
180 | hash
181 |
182 | cQA2D7311Y5BS+yRjqXaoMTLGsE=
183 |
184 | hash2
185 |
186 | /lvx5ZsVaMR7aAuIrA3pMnJq8Y9rU1q6+v3Dry9OaPk=
187 |
188 |
189 | AppIcon20x20@3x.png
190 |
191 | hash
192 |
193 | x0oQEZHvnDK31K5WuHtIqORHB8M=
194 |
195 | hash2
196 |
197 | UBHAjlJI2yNrwDEsZ3qqd584S15qDyEmH7O2l26oJAQ=
198 |
199 |
200 | AppIcon29x29@2x.png
201 |
202 | hash
203 |
204 | 7I1dHNemalKrg/gMTiFwgwcXdsM=
205 |
206 | hash2
207 |
208 | R0yvn717jCZEwSxk6Kagq1ASFSSlqG7SH3/JYENubOA=
209 |
210 |
211 | AppIcon29x29@3x.png
212 |
213 | hash
214 |
215 | w5oSziIFTapWAd2hVLfLHW7AjS4=
216 |
217 | hash2
218 |
219 | fJs46g2Tw89C8LZwLjbjrhzYyddUS0eT3bKF5YT2Axc=
220 |
221 |
222 | AppIcon40x40@2x.png
223 |
224 | hash
225 |
226 | yd8J3m2ix7thyDKAybUzHVeebkY=
227 |
228 | hash2
229 |
230 | Ek4f8vkBdaHborzTv9ukRYOkImXK6ZsJXTUYkcftJF8=
231 |
232 |
233 | AppIcon40x40@3x.png
234 |
235 | hash
236 |
237 | A8iXBEunjDTpgCglx+B0lu/ZW0Q=
238 |
239 | hash2
240 |
241 | VyrYS6kA+FxrzEEx6tukwEcQvqGU8LtK9opqKcqfvr8=
242 |
243 |
244 | AppIcon60x60@2x.png
245 |
246 | hash
247 |
248 | A8iXBEunjDTpgCglx+B0lu/ZW0Q=
249 |
250 | hash2
251 |
252 | VyrYS6kA+FxrzEEx6tukwEcQvqGU8LtK9opqKcqfvr8=
253 |
254 |
255 | AppIcon60x60@3x.png
256 |
257 | hash
258 |
259 | +uzoK4t4OJvCZfnnvi1OSqbGbDQ=
260 |
261 | hash2
262 |
263 | ngUJoIEyMqZLYRyuaS4AM6z2r+OqYpOGCfAHqGdk1m8=
264 |
265 |
266 | Assets.car
267 |
268 | hash
269 |
270 | fFo5EUmn9fwj5tzxyT6C8FZq3vQ=
271 |
272 | hash2
273 |
274 | ksZVqEQTf3hHcEBWd28GAeOkQdrrFfm1pfi2NYMGDGY=
275 |
276 |
277 | Entypo.ttf
278 |
279 | hash
280 |
281 | R4cKZ91Qhxdl95nKqX2ochnuR8U=
282 |
283 | hash2
284 |
285 | 3QhJoVkfiNp5N7I/kiQYpc7FTgdeCePMyo/rYgFvqoI=
286 |
287 |
288 | EvilIcons.ttf
289 |
290 | hash
291 |
292 | kdN36jz0dJCyVsLtCBcEp9q9rgw=
293 |
294 | hash2
295 |
296 | pcrrTTlcXjLx1aMKyzgq68Zk8brf0UkxmQfyIV5OPiY=
297 |
298 |
299 | Feather.ttf
300 |
301 | hash
302 |
303 | N8tVG0ETiQxSP0aeapsrKcTEm+Q=
304 |
305 | hash2
306 |
307 | vJZj1K7YcJfMyjc62U/QjeJKxKNRAOPfO30oFCyQCUo=
308 |
309 |
310 | FontAwesome.ttf
311 |
312 | hash
313 |
314 | E7HqtlqYPHpzvHmXxHnWaUP3xss=
315 |
316 | hash2
317 |
318 | qljzPyOaD7AvXHpsRcBD16msmgkzNYBmlOzW1O3A1qg=
319 |
320 |
321 | FontAwesome5_Brands.ttf
322 |
323 | hash
324 |
325 | GeMCdg454lpfjZDWzQFk72zXT4w=
326 |
327 | hash2
328 |
329 | NlFjtwbIzvX8bGmgoN38QLXHJtWpVfwqLOxQ3qzXeSg=
330 |
331 |
332 | FontAwesome5_Regular.ttf
333 |
334 | hash
335 |
336 | wUAIWDOjir7Gt9+Z1Mysk+smYDE=
337 |
338 | hash2
339 |
340 | rlr07d3JsGDC71CcsJ6+GkaD5oljOBFDRoDfMZ/qUQc=
341 |
342 |
343 | FontAwesome5_Solid.ttf
344 |
345 | hash
346 |
347 | xEWGSpZGlI4Nf/RJMK1zLuYUJ9g=
348 |
349 | hash2
350 |
351 | UvbXegBXJ/S5IFERnnbplWt+5xvywiOFgZr7GobSiqQ=
352 |
353 |
354 | Foundation.ttf
355 |
356 | hash
357 |
358 | SyvObHkkk6SlcWtv7C2+/olJLD8=
359 |
360 | hash2
361 |
362 | fh3QPdTOkLZYBSVUzXRZ3xZxZxc4mlUvpMbVal+JM+Y=
363 |
364 |
365 | Ionicons.ttf
366 |
367 | hash
368 |
369 | mRu3+slwnNWNo3kBdw79RwPFQu0=
370 |
371 | hash2
372 |
373 | INFzvLYFHQlzvgymqi+08npbKQ2AEGyyxWfI/cdyxxE=
374 |
375 |
376 | LaunchImage-1100-Portrait-2436h@3x.png
377 |
378 | hash
379 |
380 | WVMhrESCCLI1t9yIOtrcuL+3Xxw=
381 |
382 | hash2
383 |
384 | rzLjosQCKBURKlt1GGImS6VTomcyAVZVmbDY7L4MEJ8=
385 |
386 |
387 | LaunchImage-700-568h@2x.png
388 |
389 | hash
390 |
391 | EWkGx/uPO2x11IQOfOPBNRFujc8=
392 |
393 | hash2
394 |
395 | /GoELurqPQ8mDNB6QgjM9Lit+475eFt0aJJXw9C+6Tw=
396 |
397 |
398 | LaunchImage-800-667h@2x.png
399 |
400 | hash
401 |
402 | GohLdllr7BPHrWsF1KypmMzdKUw=
403 |
404 | hash2
405 |
406 | ezgQ+luY/nAcGF/84iMXFkuberXfpu2u1E1sZrj/XcU=
407 |
408 |
409 | LaunchImage-800-Portrait-736h@3x.png
410 |
411 | hash
412 |
413 | wIAJDjWk3HIwS+XL2l8819swQPE=
414 |
415 | hash2
416 |
417 | lQqv8QAGSpt0kprQhNJlfZH/9QDlIEmDRsllBrTXv/o=
418 |
419 |
420 | LaunchImage.png
421 |
422 | hash
423 |
424 | 8w6cSczMaWkzN7+6DFpjZ1WZTWQ=
425 |
426 | hash2
427 |
428 | Sf7YgE74cPk62E5A73W+4ObteNPPuYGLGu4EqLE2+/s=
429 |
430 |
431 | MaterialCommunityIcons.ttf
432 |
433 | hash
434 |
435 | S1x3dOYog1mECtkRU/Ko2+92DD8=
436 |
437 | hash2
438 |
439 | 9TfAzAnJLqAXEVh/QzQ9l4FAl3HGtS4KVqVdOpLoZvE=
440 |
441 |
442 | MaterialIcons.ttf
443 |
444 | hash
445 |
446 | /AXeMSNOAJD33cKM4bI69AJssdo=
447 |
448 | hash2
449 |
450 | t/Sjq1YgSPKN0fppFgG8QzY6YdD4dtFtgxbFLk8y1pY=
451 |
452 |
453 | Octicons.ttf
454 |
455 | hash
456 |
457 | o/QP7s8JqAqYbxLVfGRtK0Wa+so=
458 |
459 | hash2
460 |
461 | 8KI41G1nSeYBwS8g+PwDIB8Ze5/jR75MLJRP/FxLYDU=
462 |
463 |
464 | SimpleLineIcons.ttf
465 |
466 | hash
467 |
468 | n/uBpaEREuKS8swyPphIa61ZdZk=
469 |
470 | hash2
471 |
472 | P1Ad2wXHCCm7tRz+nKn/9X854GBFfCV7PM8l33Z/CHA=
473 |
474 |
475 | Zocial.ttf
476 |
477 | hash
478 |
479 | C9pZx7zT05J94EfgkYdaRCi/0as=
480 |
481 | hash2
482 |
483 | 17EKHr4YMOWi8I9JA7moDiwZEsDdL3O5P88r+DIhZgI=
484 |
485 |
486 | assets/js/assets/webdriverio.png
487 |
488 | hash
489 |
490 | bzB5QCc/0qI/v7xgSfSg+bZBY6E=
491 |
492 | hash2
493 |
494 | A7c7hbBu6SKCh7qV4duxg2WBs6CgwH2pcDikcJQRAu8=
495 |
496 |
497 | assets/node_modules/@tele2/react-native-select-input/src/icons/arrowDown.png
498 |
499 | hash
500 |
501 | EYQ62FQkMWvWIjm4HdYHdmoVNSU=
502 |
503 | hash2
504 |
505 | uwri/agrTNpF25UBmIPQzOn/ceX0rSzsHUvVb432Cjg=
506 |
507 |
508 | assets/node_modules/@tele2/react-native-select-input/src/icons/arrowUp.png
509 |
510 | hash
511 |
512 | 10I7Y4F+kHEkxHvKSNQwjAlHeTM=
513 |
514 | hash2
515 |
516 | tPZsy9GmTJOwa50Z1OnS4f9XalgNHAwMRoif4ELuexM=
517 |
518 |
519 | assets/node_modules/react-native-elements/src/rating/images/bell.png
520 |
521 | hash
522 |
523 | mRk2D6wOdyusOvkEInbyL3K/E6k=
524 |
525 | hash2
526 |
527 | MVdJITYj1tDwle06K+p8IFp8haF5kBT3gxuzDfc9AYg=
528 |
529 |
530 | assets/node_modules/react-native-elements/src/rating/images/heart.png
531 |
532 | hash
533 |
534 | rhZVvqRdTKoU0IrsdqQezFd0zb8=
535 |
536 | hash2
537 |
538 | v2rfzDt3/cDiJKjdhP8ejuEJZF2q6bsySGtwzOb8AxY=
539 |
540 |
541 | assets/node_modules/react-native-elements/src/rating/images/rocket.png
542 |
543 | hash
544 |
545 | mqOYKD+48iI8i2r6/LHKVlm0RGw=
546 |
547 | hash2
548 |
549 | ICOGuBMxnevPKkpTB/Aa5C5FHGGdwlrVPfiIpgRfeqk=
550 |
551 |
552 | assets/node_modules/react-native-elements/src/rating/images/star.png
553 |
554 | hash
555 |
556 | XPFaCu1j/HeeE7zoK38ulP635qc=
557 |
558 | hash2
559 |
560 | QomdN3rBYNJR6hzK8VcKZmuxkf8KClRArNMi+Fxau5U=
561 |
562 |
563 | assets/node_modules/react-navigation-stack/dist/views/assets/back-icon-mask.png
564 |
565 | hash
566 |
567 | twCElRF9b860vkYvLPGRVtwtBcA=
568 |
569 | hash2
570 |
571 | qPaOshDnK+iP+MqrK2VwfgeqJN7zzzEIZ75i1AijBds=
572 |
573 |
574 | assets/node_modules/react-navigation-stack/dist/views/assets/back-icon.png
575 |
576 | hash
577 |
578 | keLOi1inJdXs0IRSKnXqyhW57Aw=
579 |
580 | hash2
581 |
582 | LN/rjlzN55dvcBL7jM5zryIpAp7iHU8VCf7RFIccbNg=
583 |
584 |
585 | assets/node_modules/react-navigation-stack/dist/views/assets/back-icon@2x.png
586 |
587 | hash
588 |
589 | rSvG8m4uPMSItIcsIF+N2tDJD8U=
590 |
591 | hash2
592 |
593 | K3RDqaWOksoRpXW9wRWYYVpX3eMFzYznDWAmBrMCzZg=
594 |
595 |
596 | assets/node_modules/react-navigation-stack/dist/views/assets/back-icon@3x.png
597 |
598 | hash
599 |
600 | 8kFG8Vv7Hfrw4yVcFrhUhbHieBA=
601 |
602 | hash2
603 |
604 | Pd0Hc+0n4j0leJ8wFzGzrEVa2L5aonoKG4OPicbSciU=
605 |
606 |
607 | main.jsbundle
608 |
609 | hash
610 |
611 | ncuRxpKp81bWfMSflTw2td5B/e4=
612 |
613 | hash2
614 |
615 | MXWV1yyyW6sNGt+EiY5hESTD62Vp3tJ8CCR4eVEQ91s=
616 |
617 |
618 |
619 | rules
620 |
621 | ^.*
622 |
623 | ^.*\.lproj/
624 |
625 | optional
626 |
627 | weight
628 | 1000
629 |
630 | ^.*\.lproj/locversion.plist$
631 |
632 | omit
633 |
634 | weight
635 | 1100
636 |
637 | ^Base\.lproj/
638 |
639 | weight
640 | 1010
641 |
642 | ^version.plist$
643 |
644 |
645 | rules2
646 |
647 | .*\.dSYM($|/)
648 |
649 | weight
650 | 11
651 |
652 | ^(.*/)?\.DS_Store$
653 |
654 | omit
655 |
656 | weight
657 | 2000
658 |
659 | ^.*
660 |
661 | ^.*\.lproj/
662 |
663 | optional
664 |
665 | weight
666 | 1000
667 |
668 | ^.*\.lproj/locversion.plist$
669 |
670 | omit
671 |
672 | weight
673 | 1100
674 |
675 | ^Base\.lproj/
676 |
677 | weight
678 | 1010
679 |
680 | ^Info\.plist$
681 |
682 | omit
683 |
684 | weight
685 | 20
686 |
687 | ^PkgInfo$
688 |
689 | omit
690 |
691 | weight
692 | 20
693 |
694 | ^embedded\.provisionprofile$
695 |
696 | weight
697 | 20
698 |
699 | ^version\.plist$
700 |
701 | weight
702 | 20
703 |
704 |
705 |
706 |
707 |
--------------------------------------------------------------------------------
/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/assets/js/assets/webdriverio.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prashanth-sams/python-appium-framework/7b75bd44366758192a385acbec9a64ec987d3afe/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/assets/js/assets/webdriverio.png
--------------------------------------------------------------------------------
/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/assets/node_modules/@tele2/react-native-select-input/src/icons/arrowDown.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prashanth-sams/python-appium-framework/7b75bd44366758192a385acbec9a64ec987d3afe/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/assets/node_modules/@tele2/react-native-select-input/src/icons/arrowDown.png
--------------------------------------------------------------------------------
/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/assets/node_modules/@tele2/react-native-select-input/src/icons/arrowUp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prashanth-sams/python-appium-framework/7b75bd44366758192a385acbec9a64ec987d3afe/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/assets/node_modules/@tele2/react-native-select-input/src/icons/arrowUp.png
--------------------------------------------------------------------------------
/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/assets/node_modules/react-native-elements/src/rating/images/bell.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prashanth-sams/python-appium-framework/7b75bd44366758192a385acbec9a64ec987d3afe/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/assets/node_modules/react-native-elements/src/rating/images/bell.png
--------------------------------------------------------------------------------
/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/assets/node_modules/react-native-elements/src/rating/images/heart.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prashanth-sams/python-appium-framework/7b75bd44366758192a385acbec9a64ec987d3afe/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/assets/node_modules/react-native-elements/src/rating/images/heart.png
--------------------------------------------------------------------------------
/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/assets/node_modules/react-native-elements/src/rating/images/rocket.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prashanth-sams/python-appium-framework/7b75bd44366758192a385acbec9a64ec987d3afe/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/assets/node_modules/react-native-elements/src/rating/images/rocket.png
--------------------------------------------------------------------------------
/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/assets/node_modules/react-native-elements/src/rating/images/star.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prashanth-sams/python-appium-framework/7b75bd44366758192a385acbec9a64ec987d3afe/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/assets/node_modules/react-native-elements/src/rating/images/star.png
--------------------------------------------------------------------------------
/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/assets/node_modules/react-navigation-stack/dist/views/assets/back-icon-mask.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prashanth-sams/python-appium-framework/7b75bd44366758192a385acbec9a64ec987d3afe/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/assets/node_modules/react-navigation-stack/dist/views/assets/back-icon-mask.png
--------------------------------------------------------------------------------
/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/assets/node_modules/react-navigation-stack/dist/views/assets/back-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prashanth-sams/python-appium-framework/7b75bd44366758192a385acbec9a64ec987d3afe/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/assets/node_modules/react-navigation-stack/dist/views/assets/back-icon.png
--------------------------------------------------------------------------------
/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/assets/node_modules/react-navigation-stack/dist/views/assets/back-icon@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prashanth-sams/python-appium-framework/7b75bd44366758192a385acbec9a64ec987d3afe/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/assets/node_modules/react-navigation-stack/dist/views/assets/back-icon@2x.png
--------------------------------------------------------------------------------
/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/assets/node_modules/react-navigation-stack/dist/views/assets/back-icon@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prashanth-sams/python-appium-framework/7b75bd44366758192a385acbec9a64ec987d3afe/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/assets/node_modules/react-navigation-stack/dist/views/assets/back-icon@3x.png
--------------------------------------------------------------------------------
/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/wdioDemoApp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prashanth-sams/python-appium-framework/7b75bd44366758192a385acbec9a64ec987d3afe/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app/wdioDemoApp
--------------------------------------------------------------------------------
/pytest.ini:
--------------------------------------------------------------------------------
1 | [pytest]
2 | json_report = report/json/report.json
3 | markers =
4 | login: mark as login tests
5 | home: mark as home tests
6 | addopts = -vs -rf --html-report=./report
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | # Python Appium Framework
2 | > Complete Python Appium framework in 360 degree
3 |
4 | ## Features
5 | - [x] Locator strategy
6 | - [x] Hooks (unittest)
7 | - [x] Helper methods
8 | - [x] Database connectivity + SSH Tunneling
9 | - [x] Screenshot on failure
10 | - [x] Docker support for Android
11 | - [x] Handle local storage
12 | - [x] Bash Runner
13 | - [x] Slack notify
14 | - [x] Define environment variable
15 | - [x] HTML report
16 | - [x] JSON report
17 | - [x] Allure report
18 | - [x] CLI arguments as a fixture (Pytest)
19 | - [x] In-house data storage
20 | - [x] Logger
21 | - [x] Runner (Pytest)
22 | - [x] Runner percentage with style (Pytest)
23 | - [x] Parallel Tests (Pytest) x2
24 | - [x] Re-run failures (Pytest)
25 | - [x] Test script validation
26 |
27 | ## Installation
28 | Install python libraries
29 |
30 | pip3 install -r requirements.txt
31 |
32 | ## Test Runner
33 |
34 | | Action | Command |
35 | | -------------- | --------- |
36 | | Bash runner | `bash runner/android/smoke_run.sh` |
37 | | Default | `python3 -m pytest src/spec/* --app=android` |
38 | | Rerun failures | `python3 -m pytest src/spec/home_test.py --app=android --reruns 1` |
39 | | Parallel Test | `python3 -m pytest src/spec/home_test.py --app=android -v -n2` |
40 |
41 | #### Docker Run
42 | > Android test - x1 run
43 | ```shell script
44 | docker run --privileged -d -p 6080:6080 -p 4723:4723 -p 5554:5554 -p 5555:5555 \
45 | -v $(pwd)/data/apps/Android-NativeDemoApp-0.2.1.apk:/root/tmp/Android-NativeDemoApp-0.2.1.apk \
46 | -e DEVICE="Samsung Galaxy S9" -e APPIUM=true --name android-container \
47 | budtmo/docker-android-x86-11.0
48 | ```
49 | **noVnc interface:** http://localhost:6080
50 |
51 | ## Test Report
52 | | Type | Command |
53 | | -------------- | --------- |
54 | | HTML Report | `python3 -m pytest src/spec/android/*.py --html-report=report/report.html --app=android` |
55 | | JSON Report | `python3 -m pytest src/spec/android/*.py --json=report/json/report.json --app=android` |
56 | | Allure Report | `python3 -m pytest src/spec/android/* --alluredir=report --app=android` |
57 |
58 | - Download allure commandline
59 | https://github.com/allure-framework/allure2/releases
60 |
61 | > generate allure report
62 | ```
63 | allure serve report/
64 | ```
65 |
66 | ## Wrapper Methods
67 | | Methods | Usage |
68 | | -------------- | --------- |
69 | | element | `App.element(self, locator)` |
70 | | elements | `App.elements(self, locactor)` |
71 | | is_displayed | `App.is_displayed(self, locator)` |
72 | | is_displayed > elements | `App.is_displayed(self, locator, index=0)` |
73 | | is_exist | `App.is_exist(self, locator)` |
74 | | is_exist > elements | `App.is_exist(self, locator, index=0)` |
75 | | tap | `App.tap(self, locator)` |
76 | | tap > elements | `App.tap(self, locator, index=0)` |
77 | | double_tap | `App.double_tap(self, locator)` |
78 | | double_tap > elements | `App.double_tap(self, locator, index=0)` |
79 | | click | `App.click(self, locator)` |
80 | | click > elements | `App.click(self, locator, index=0)` |
81 | | swipe | `App.swipe(self, start=locator, dest=locator)` |
82 | | swipe > elements | `App.swipe(self, start=(locator, 2), dest=(locator, 1))` |
83 | | send_keys | `App.send_keys(self, locator, 'text')` |
84 | | send_keys > elements | `App.send_keys(self, locator, 'text', index=0)` |
85 | | get_screen_size | `App.get_screen_size(self)` |
86 | | back | `App.back(self)` |
87 | | close | `App.close(self)` |
88 | | reset | `App.reset(self)` |
89 | | launch_app | `App.send_keys(self, locator, 'text'` |
90 | | tap_by_coordinates | `App.tap_by_coordinates(self, x=338, y=204)` |
91 | | assert_text | `App.assert_text(self, 'actual', 'expected')` |
92 | | assert_text > elements | `App.assert_text(self, 'actual', 'expected', index=0)` |
93 | | assert_size | `App.assert_size(self, locator, 'more than 1')` |
94 | | | `App.assert_size(self, locator, 'greater than 1')` |
95 | | | `App.assert_size(self, locator, 'above 1')` |
96 | | | `App.assert_size(self, locator, '> 1')` |
97 | | | `App.assert_size(self, locator, 'less than 1')` |
98 | | | `App.assert_size(self, locator, 'below 1')` |
99 | | | `App.assert_size(self, locator, '< 1')` |
100 | | | `App.assert_size(self, locator, 'equal to 1')` |
101 | | | `App.assert_size(self, locator, '== 1')` |
102 | | assert_boolean | `App.assert_boolean(True, True)` |
103 | | swipe_until | `App.swipe_until(self, locator, start_x=144, start_y=434, count=20)` |
104 |
105 | 
--------------------------------------------------------------------------------
/report/6d01bfcc-98f1-4278-a4c5-6fc2b55772bb-result.json:
--------------------------------------------------------------------------------
1 | {"name": "test_home", "status": "passed", "start": 1568110276163, "stop": 1568110280537, "uuid": "3e181cfe-ab4e-4ea2-9b31-1232faae8524", "historyId": "69ffa3a2de0c03e2b51e0e5d26784d58", "testCaseId": "2b0e6fdfbc23c9f24893fcd242aaa5a7", "fullName": "src.spec.home_test.HomeTest#test_home", "labels": [{"name": "parentSuite", "value": "src.spec"}, {"name": "suite", "value": "home_test"}, {"name": "subSuite", "value": "HomeTest"}, {"name": "host", "value": "Prashanth-Rajjapa-MacBook-Pro.local"}, {"name": "thread", "value": "49965-MainThread"}, {"name": "framework", "value": "pytest"}, {"name": "language", "value": "cpython3"}, {"name": "package", "value": "src.spec.home_test"}]}
--------------------------------------------------------------------------------
/report/assets/style.css:
--------------------------------------------------------------------------------
1 | body {
2 | font-family: Helvetica, Arial, sans-serif;
3 | font-size: 12px;
4 | min-width: 1200px;
5 | color: #999;
6 | }
7 |
8 | h1 {
9 | font-size: 24px;
10 | color: black;
11 | }
12 |
13 | h2 {
14 | font-size: 16px;
15 | color: black;
16 | }
17 |
18 | p {
19 | color: black;
20 | }
21 |
22 | a {
23 | color: #999;
24 | }
25 |
26 | table {
27 | border-collapse: collapse;
28 | }
29 |
30 | /******************************
31 | * SUMMARY INFORMATION
32 | ******************************/
33 |
34 | #environment td {
35 | padding: 5px;
36 | border: 1px solid #E6E6E6;
37 | }
38 |
39 | #environment tr:nth-child(odd) {
40 | background-color: #f6f6f6;
41 | }
42 |
43 | /******************************
44 | * TEST RESULT COLORS
45 | ******************************/
46 | span.passed, .passed .col-result {
47 | color: green;
48 | }
49 | span.skipped, span.xfailed, span.rerun, .skipped .col-result, .xfailed .col-result, .rerun .col-result {
50 | color: orange;
51 | }
52 | span.error, span.failed, span.xpassed, .error .col-result, .failed .col-result, .xpassed .col-result {
53 | color: red;
54 | }
55 |
56 |
57 | /******************************
58 | * RESULTS TABLE
59 | *
60 | * 1. Table Layout
61 | * 2. Extra
62 | * 3. Sorting items
63 | *
64 | ******************************/
65 |
66 | /*------------------
67 | * 1. Table Layout
68 | *------------------*/
69 |
70 | #results-table {
71 | border: 1px solid #e6e6e6;
72 | color: #999;
73 | font-size: 12px;
74 | width: 100%
75 | }
76 |
77 | #results-table th, #results-table td {
78 | padding: 5px;
79 | border: 1px solid #E6E6E6;
80 | text-align: left
81 | }
82 | #results-table th {
83 | font-weight: bold
84 | }
85 |
86 | /*------------------
87 | * 2. Extra
88 | *------------------*/
89 |
90 | .log:only-child {
91 | height: inherit
92 | }
93 | .log {
94 | background-color: #e6e6e6;
95 | border: 1px solid #e6e6e6;
96 | color: black;
97 | display: block;
98 | font-family: "Courier New", Courier, monospace;
99 | height: 230px;
100 | overflow-y: scroll;
101 | padding: 5px;
102 | white-space: pre-wrap
103 | }
104 | div.image {
105 | border: 1px solid #e6e6e6;
106 | float: right;
107 | height: 240px;
108 | margin-left: 5px;
109 | overflow: hidden;
110 | width: 320px
111 | }
112 | div.image img {
113 | width: 320px
114 | }
115 | .collapsed {
116 | display: none;
117 | }
118 | .expander::after {
119 | content: " (show details)";
120 | color: #BBB;
121 | font-style: italic;
122 | cursor: pointer;
123 | }
124 | .collapser::after {
125 | content: " (hide details)";
126 | color: #BBB;
127 | font-style: italic;
128 | cursor: pointer;
129 | }
130 |
131 | /*------------------
132 | * 3. Sorting items
133 | *------------------*/
134 | .sortable {
135 | cursor: pointer;
136 | }
137 |
138 | .sort-icon {
139 | font-size: 0px;
140 | float: left;
141 | margin-right: 5px;
142 | margin-top: 5px;
143 | /*triangle*/
144 | width: 0;
145 | height: 0;
146 | border-left: 8px solid transparent;
147 | border-right: 8px solid transparent;
148 | }
149 |
150 | .inactive .sort-icon {
151 | /*finish triangle*/
152 | border-top: 8px solid #E6E6E6;
153 | }
154 |
155 | .asc.active .sort-icon {
156 | /*finish triangle*/
157 | border-bottom: 8px solid #999;
158 | }
159 |
160 | .desc.active .sort-icon {
161 | /*finish triangle*/
162 | border-top: 8px solid #999;
163 | }
164 |
--------------------------------------------------------------------------------
/report/c5704f6f-6816-476a-83df-b5b8b491dee2-container.json:
--------------------------------------------------------------------------------
1 | {"uuid": "e2a6491c-034f-4e80-9361-a478aba9f06d", "children": ["3e181cfe-ab4e-4ea2-9b31-1232faae8524"], "befores": [{"name": "_UnitTestCase__pytest_class_setup", "status": "passed", "start": 1568110276162, "stop": 1568110276162}], "afters": [{"name": "_UnitTestCase__pytest_class_setup::0", "status": "passed", "start": 1568110280538, "stop": 1568110280538}], "start": 1568110276162, "stop": 1568110280538}
--------------------------------------------------------------------------------
/report/report.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Test Report
6 |
7 |
8 |
243 | report.html
244 | Report generated on 10-Sep-2019 at 15:47:45 by pytest-html v2.0.0
245 | Environment
246 |
247 |
248 | Packages |
249 | {'pytest': '5.1.1', 'py': '1.8.0', 'pluggy': '0.12.0'} |
250 |
251 | Platform |
252 | Darwin-18.6.0-x86_64-i386-64bit |
253 |
254 | Plugins |
255 | {'html': '2.0.0', 'allure-pytest': '2.8.4', 'metadata': '1.8.0'} |
256 |
257 | Python |
258 | 3.7.3 |
259 | Summary
260 | 1 tests ran in 5.77 seconds.
261 | (Un)check the boxes to filter the results.
1 passed, 0 skipped, 0 failed, 0 errors, 0 expected failures, 0 unexpected passes
262 | Results
263 |
264 |
265 |
266 | Result |
267 | Test |
268 | Duration |
269 | Links |
270 |
271 | No results found. Try to check the filters |
272 |
273 |
274 | Passed |
275 | src/spec/home_test.py::HomeTest::test_home |
276 | 5.62 |
277 | |
278 |
279 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | Appium-Python-Client~=1.0.2
2 | selenium~=3.141.0
3 | pytest~=6.1.1
4 | allure-pytest
5 | pytest-parallel
6 | pytest-xdist
7 | pytest-rerunfailures
8 | pytest-sugar
9 | pytest-json
10 | pymysql~=0.10.1
11 | sshtunnel~=0.1.5
12 | requests~=2.24.0
13 | invoke~=1.4.1
14 | python-dotenv
15 | pytest-html-reporter~=0.2.3
--------------------------------------------------------------------------------
/runner/android/smoke_run.sh:
--------------------------------------------------------------------------------
1 | invoke test --env='staging' --lang='en' --app='android' --device='emulator'
2 | invoke slack --env='staging' --lang='en' --slack='on' --app='android'
--------------------------------------------------------------------------------
/runner/ios/smoke_run.sh:
--------------------------------------------------------------------------------
1 | invoke test --env='staging' --lang='en' --app='ios' --device='simulator'
2 | invoke slack --env='staging' --lang='en' --slack='on' --app='ios'
--------------------------------------------------------------------------------
/runner/ios/smoke_run_bitrise.sh:
--------------------------------------------------------------------------------
1 | invoke test --env='staging' --lang='en' --app='ios' --device='bitrise'
2 | invoke slack --env='staging' --lang='en' --slack='off' --app='ios'
--------------------------------------------------------------------------------
/screenshots/test_home_2019-09-10_13-29-38.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prashanth-sams/python-appium-framework/7b75bd44366758192a385acbec9a64ec987d3afe/screenshots/test_home_2019-09-10_13-29-38.png
--------------------------------------------------------------------------------
/settings.py:
--------------------------------------------------------------------------------
1 | import os
2 | from os.path import join, dirname
3 | from dotenv import load_dotenv
4 |
5 | dotenv_path = join(dirname(__file__), '.env')
6 | load_dotenv(dotenv_path)
7 |
8 | SLACK_TOKEN = os.getenv('SLACK_TOKEN')
9 | UDID = os.getenv('UDID')
--------------------------------------------------------------------------------
/src/helpers/app.py:
--------------------------------------------------------------------------------
1 | from selenium.webdriver.support.wait import WebDriverWait
2 | from src.helpers.appiumdriver import Driver
3 | from appium.webdriver.common.touch_action import TouchAction
4 | from selenium.common.exceptions import NoSuchElementException
5 | from selenium.webdriver.support import expected_conditions as EC
6 | import time
7 |
8 |
9 | def keyword_check(kwargs):
10 | kc = {}
11 | if 'index' in kwargs: kc['index'] = 'elements'
12 | if 'index' not in kwargs: kc['index'] = 'element'
13 | return ''.join(kc.values())
14 |
15 |
16 | class App(Driver):
17 |
18 | def __init__(self, driver):
19 | super().__init__(driver)
20 |
21 | def element(self, locator, n=3):
22 | """
23 | locate an element by polling if element not found
24 | maximum poll #2 with approx. ~10 secs
25 | """
26 | wait = WebDriverWait(self.driver, 20)
27 |
28 | x = iter(CustomCall())
29 | while n > 1:
30 | try:
31 | wait.until(EC.visibility_of_element_located(locator))
32 | return self.driver.find_element(*locator)
33 | except Exception as e:
34 | self.logger.error(f"element failed attempt {next(x)} - {locator}")
35 | n -= 1
36 | if n == 1: raise NoSuchElementException("Could not locate element with value: %s" % str(locator))
37 |
38 | def elements(self, locator, n=3):
39 | """
40 | locate element list by polling if the element list is not found
41 | maximum poll #2 with approx. ~10 secs
42 | """
43 | wait = WebDriverWait(self.driver, 20)
44 |
45 | x = iter(CustomCall())
46 | while n > 1:
47 | try:
48 | wait.until(EC.visibility_of_any_elements_located(locator))
49 | return self.driver.find_elements(*locator)
50 | except Exception as e:
51 | self.logger.error(f"element list failed attempt {next(x)} - {locator}")
52 | n -= 1
53 | if n == 1: raise NoSuchElementException("Could not locate element list with value: %s" % str(locator))
54 |
55 | def is_displayed(self, locator, expected=True, n=3, **kwargs):
56 | """
57 | assert boolean value by polling if match is not found
58 | maximum poll #3 with approx. ~10 secs
59 | """
60 | wait = WebDriverWait(self.driver, 20)
61 |
62 | x = iter(CustomCall())
63 | while n > 1:
64 | try:
65 | if len(kwargs) == 0:
66 | wait.until(EC.visibility_of_element_located(locator))
67 | assert self.driver.find_element(*locator).is_displayed() == expected
68 | else:
69 | assert self.driver.find_elements(*locator)[kwargs['index']].is_displayed() == expected
70 | break
71 | except Exception as e:
72 | self.logger.error(f'is_displayed failed attempt {next(x)}- {locator}')
73 | time.sleep(0.5)
74 | n -= 1
75 | if n == 1: assert False == expected
76 |
77 | def is_exist(self, locator, expected=True, n=3, **kwargs):
78 | """
79 | returns boolean value by polling if match is not found or not
80 | maximum poll #3 with approx. ~10 secs
81 | """
82 | while n > 1:
83 | try:
84 | if len(kwargs) == 0 and self.driver.find_element(*locator).is_displayed() == expected:
85 | return True
86 | elif self.driver.find_elements(*locator)[kwargs['index']].is_displayed() == expected:
87 | return True
88 | except Exception as e:
89 | n -= 1
90 | if n == 1: return False
91 |
92 | def tap(self, locator, **kwargs):
93 | """
94 | custom wrapped single tap method
95 | -> wait until display
96 | -> element(s)
97 | """
98 | App.is_displayed(self, locator, True)
99 |
100 | actions = TouchAction(self.driver)
101 | return {
102 | 'element': lambda x: actions.tap(App.element(self, locator)).perform(),
103 | 'elements': lambda x: actions.tap(App.elements(self, locator)[kwargs['index']]).perform()
104 | }[keyword_check(kwargs)]('x')
105 |
106 | def double_tap(self, locator, n=3, **kwargs):
107 | """
108 | custom wrapped double tap method
109 | -> wait for element until display
110 | -> element(s)
111 | """
112 | App.is_displayed(self, locator, True, n=n)
113 |
114 | actions = TouchAction(self.driver)
115 | return {
116 | 'element': lambda x: actions.tap(App.element(self, locator), count=2).perform(),
117 | 'elements': lambda x: actions.tap(App.elements(self, locator)[kwargs['index']], count=2).perform()
118 | }[keyword_check(kwargs)]('x')
119 |
120 | def click(self, locator, n=3, **kwargs):
121 | """
122 | custom wrapped click method
123 | -> wait for element until display
124 | -> element(s)
125 | """
126 | App.sleep(kwargs)
127 | App.is_displayed(self, locator, True, n=n)
128 |
129 | return {
130 | 'element': lambda x: App.element(self, locator).click(),
131 | 'elements': lambda x: App.elements(self, locator)[kwargs['index']].click()
132 | }[keyword_check(kwargs)]('x')
133 |
134 | def wait_until_disappear(self, locator, n=3, **kwargs):
135 | wait = WebDriverWait(self.driver, 25)
136 | wait.until(EC.invisibility_of_element_located(locator))
137 |
138 | @staticmethod
139 | def sleep(kwargs):
140 | try:
141 | time.sleep(kwargs['sleep'])
142 | except KeyError:
143 | pass
144 |
145 | def send_keys(self, locator, text='', **kwargs):
146 | """
147 | custom wrapped send_keys method
148 | -> wait for element until display
149 | -> element(s)
150 | """
151 | App.is_displayed(self, locator, True)
152 |
153 | return {
154 | 'element': lambda text: App.element(self, locator).clear() and App.element(self, locator).send_keys(text),
155 | 'elements': lambda text: App.elements(self, locator)[kwargs['index']].clear() and App.elements(self, locator)[kwargs['index']].send_keys(text)
156 | }[keyword_check(kwargs)](text)
157 |
158 | def get_screen_size(self):
159 | return self.driver.get_window_size()
160 |
161 | def back(self):
162 | """
163 | generally minimize app
164 | """
165 | self.driver.back()
166 |
167 | def close(self):
168 | self.driver.close_app()
169 |
170 | def reset(self):
171 | self.driver.reset()
172 |
173 | def launch_app(self):
174 | self.driver.launch_app()
175 |
176 | def swipe(self, start, dest):
177 | """
178 | custom wrapped swipe / scroll method
179 | -> wait for element until display - source and destination
180 | -> element(s)
181 | """
182 | if type(start[1]) is not int:
183 | source_element = App.element(self, start)
184 | else:
185 | source_element = App.elements(self, start[0])[int(start[1])]
186 |
187 | if type(dest[1]) is not int:
188 | target_element = App.element(self, dest)
189 | else:
190 | target_element = App.elements(self, dest[0])[int(dest[1])]
191 |
192 | self.driver.scroll(source_element, target_element)
193 |
194 | def tap_by_coordinates(self, x, y):
195 | time.sleep(2)
196 | actions = TouchAction(self.driver)
197 | actions.tap(x=x, y=y).perform()
198 |
199 | # need refactor on condition
200 | def assert_text(self, locator, text, n=20, **kwargs):
201 | """
202 | assert element's text by polling if match is not found
203 | maximum poll #20 with approx. ~10 secs
204 | """
205 | App.is_displayed(self, locator, True)
206 |
207 | x = iter(CustomCall())
208 | while n > 1:
209 | try:
210 | if len(kwargs) == 0:
211 | assert App.element(self, locator).text == text
212 | else:
213 | assert App.elements(self, locator)[kwargs['index']].text == text
214 | break
215 | except Exception as e:
216 | self.logger.error(f'assert_text failed attempt {next(x)}- {locator}')
217 | time.sleep(0.5)
218 | n -= 1
219 | if len(kwargs) == 0:
220 | if n == 1: assert App.element(self, locator).text == text
221 | else:
222 | if n == 1: assert App.elements(self, locator)[kwargs['index']].text == text
223 |
224 | def assert_size(self, locator, param):
225 | """
226 | assert elements size by polling if match is found
227 | maximum poll #20 with approx. ~10 secs
228 | """
229 | App.is_displayed(self, locator, True, index=0)
230 |
231 | case = param.rsplit(None, 1)[0]
232 | value = int(param.rsplit(None, 1)[1])
233 |
234 | if case in ['more than', 'greater than', 'above', '>']:
235 | assert App.elements(self, locator).__len__() > value
236 | elif case in ['less than', 'below', '<']:
237 | assert App.elements(self, locator).__len__() < value
238 | elif case in ['equal to', '==']:
239 | assert App.elements(self, locator).__len__() == value
240 |
241 | def swipe_until(self, locator, start_x=100, start_y=200, end_x=0, end_y=0, duration=0, count=10):
242 | self.driver.implicitly_wait(0.5) # waits half a second
243 | for i in range(count):
244 | try:
245 | self.driver.find_element(*locator).is_displayed()
246 | break
247 | except Exception as e:
248 | self.driver.swipe(start_x, start_y, end_x, end_y, duration)
249 |
250 | self.driver.implicitly_wait(5) # waits 5 seconds
251 |
252 | def assert_equal(self, actual, expected, n=5):
253 | x = iter(CustomCall())
254 | while n > 1:
255 | try:
256 | assert actual == expected
257 | break
258 | except Exception as e:
259 | self.logger.error(f"assert equal attempt {next(x)} - {actual} not matching {expected}")
260 | time.sleep(2)
261 | n -= 1
262 | if n == 1: assert actual == expected
263 |
264 | def assert_equal_ab(self, actual, expected_a, expected_b, n=5):
265 | x = iter(CustomCall())
266 | while n > 1:
267 | try:
268 | try:
269 | assert actual == expected_a
270 | except Exception as e:
271 | assert actual == expected_b
272 | break
273 | except Exception as e:
274 | self.logger.error(f"assert equal attempt {next(x)} - {actual} not matching {expected_a} or {expected_b}")
275 | time.sleep(2)
276 | n -= 1
277 | if n == 1: assert actual == expected_a
278 |
279 | @staticmethod
280 | def assert_boolean(actual, expected=True):
281 | assert actual == expected
282 |
283 |
284 | class CustomCall:
285 |
286 | def __iter__(self):
287 | self.a = 1
288 | return self
289 |
290 | def __next__(self):
291 | k = self.a
292 | self.a += 1
293 | return k
--------------------------------------------------------------------------------
/src/helpers/appiumdriver.py:
--------------------------------------------------------------------------------
1 | from appium import webdriver
2 | import unittest
3 | import os
4 | from datetime import datetime
5 | import pytest
6 | from src.helpers.business import *
7 | from pytest_html_reporter import attach
8 |
9 |
10 | class Driver(unittest.TestCase):
11 |
12 | def __init__(self, driver):
13 | super().__init__(driver)
14 |
15 | def setUp(self):
16 | """
17 | This method instantiates the appium driver
18 | """
19 | global desired_caps
20 |
21 | self.logger.info("Configuring desired capabilities")
22 | if os.getenv('PYTEST_XDIST_WORKER'):
23 | if self.app == 'ios':
24 | desired_caps = {
25 | 'deviceName': 'iPhone 8',
26 | 'platformName': 'iOS',
27 | 'platformVersion': '13.3',
28 | 'automationName': 'XCUITest',
29 | 'app': f'{os.popen("pwd").read().rstrip()}/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app'
30 | }
31 |
32 | elif self.app == 'android':
33 | desired_caps = {
34 | 'platformName': 'Android',
35 | 'platformVersion': '',
36 | 'deviceName': 'PF',
37 | 'wdaLocalPort': Driver.wda_port(self),
38 | 'udid': Driver.android_device_name(self),
39 | 'app': f'{os.popen("pwd").read().rstrip()}/data/apps/app-staging-debug.apk',
40 | 'noReset': True
41 | }
42 |
43 | else:
44 | if self.app == 'ios':
45 | desired_caps = self.ios()
46 |
47 | elif self.app == 'android':
48 | desired_caps = self.android()
49 |
50 | self.logger.info("Initiating Appium driver")
51 | self.driver = webdriver.Remote("http://0.0.0.0:4723/wd/hub", desired_caps)
52 |
53 | # set waits
54 | self.driver.implicitly_wait(5) # waits 5 seconds
55 |
56 | def android(self):
57 | if self.device == 'emulator':
58 | return dict(platformName='Android', platformVersion='', deviceName='PF',
59 | app=f'{os.popen("pwd").read().rstrip()}/data/apps/Android-NativeDemoApp-0.2.1.apk', noReset=True)
60 | elif self.device == 'real device':
61 | return dict(platformName='Android', platformVersion='', deviceName='PF',
62 | app=f'{os.popen("pwd").read().rstrip()}/data/apps/Android-NativeDemoApp-0.2.1.apk', noReset=True)
63 |
64 | def ios(self):
65 | if self.device == 'simulator':
66 | return dict(platformName='iOS', platformVersion='13.3', deviceName='iPhone 11',
67 | app=f'{os.popen("pwd").read().rstrip()}/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app',
68 | automationName='XCUITest')
69 | elif self.device == 'real device':
70 | return dict(platformName='iOS', platformVersion='14.0', deviceName='iPhone X',
71 | udid=f'{UDID}', useNewWDA=True,
72 | app=f'{os.popen("pwd").read().rstrip()}/data/apps/iOS-RealDevice-NativeDemoApp-0.2.1.ipa',
73 | automationName='XCUITest')
74 | elif self.device == 'bitrise':
75 | return dict(platformName='iOS', platformVersion='13.0', deviceName='iPhone-11',
76 | udid='E04A6F53-4C3B-4810-B210-DD2015D0D064', useNewWDA=True,
77 | app=f'{os.popen("pwd").read().rstrip()}/data/apps/iOS-Simulator-NativeDemoApp-0.2.1.app', automationName='XCUITest')
78 |
79 | def tearDown(self):
80 | Driver.screenshot_on_failure(self)
81 | attach(data=self.driver.get_screenshot_as_png())
82 | self.driver.quit()
83 |
84 | def screenshot_on_failure(self):
85 | now = datetime.now().strftime('%Y-%m-%d_%H-%M-%S')
86 | test_name = self._testMethodName
87 | for self._testMethodName, error in self._outcome.errors:
88 | if error:
89 | self.logger.error("Taking screenshot on failure")
90 | if not os.path.exists('screenshots'):
91 | os.makedirs('screenshots')
92 |
93 | self.driver.save_screenshot(f"screenshots/{test_name}_{now}.png")
94 |
95 | @pytest.fixture(autouse=True)
96 | def cli(self, app, device, get_logger):
97 | self.app = app
98 | self.device = device
99 | self.logger = get_logger
100 |
101 | def wda_port(self):
102 | if os.getenv('PYTEST_XDIST_WORKER') == 'gw1':
103 | return 8101
104 | else: # include 'master' and 'gw0'
105 | return 8100
106 |
107 | def android_device_name(self):
108 | if os.getenv('PYTEST_XDIST_WORKER') == 'gw0':
109 | return 'emulator-5554'
110 | elif os.getenv('PYTEST_XDIST_WORKER') == 'gw1':
111 | return 'emulator-5556'
112 | else: # default
113 | return 'emulator-5554'
114 |
115 |
116 | if __name__ == '__main__':
117 | unittest.main()
118 |
--------------------------------------------------------------------------------
/src/helpers/business.py:
--------------------------------------------------------------------------------
1 | import datetime
2 | import pymysql
3 | import requests
4 | import json
5 | import random
6 | from sshtunnel import SSHTunnelForwarder
7 | from settings import *
8 |
9 |
10 | def db(query):
11 | with SSHTunnelForwarder(
12 | ('', 22),
13 | ssh_username="",
14 | ssh_pkey="/Users/prashanth/.ssh/id_rsa",
15 | remote_bind_address=('', 3306)
16 | ) as tunnel:
17 | conn = pymysql.connect(host='127.0.0.1', user='', password='', db='',
18 | port=tunnel.local_bind_port)
19 | cur = conn.cursor()
20 | cur.execute(query)
21 | conn.close()
22 | return get_db_results(cur)
23 |
24 |
25 | def get_db_results(db_cursor):
26 | desc = [d[0] for d in db_cursor.description]
27 | results = [dotdict(dict(zip(desc, res))) for res in db_cursor.fetchall()]
28 | return results
29 |
30 |
31 | def notify_slack():
32 | """
33 | modify web_hook_url with apt data
34 | """
35 | web_hook_url = f'https://hooks.slack.com/services/{SLACK_TOKEN}'
36 |
37 | with open("./report/json/report.json") as json_file:
38 | json_object = json.load(json_file)
39 | json_file.close()
40 |
41 | passed = int(status_count(json_object, 'passed'))
42 | failed = int(status_count(json_object, 'failed'))
43 | color = '#36a64f' if failed == 0 else '#a30001'
44 | text = "#Build Passed" if failed == 0 else "#Build Failed"
45 |
46 | slack_msg = {
47 | "attachments": [
48 | {
49 | "fallback": "Excuse Me! I've something for you!",
50 | "color": f"{color}",
51 | "pretext": f"@here {quote()}",
52 | "author_name": "Mobile Automation Results",
53 | "author_link": "https://twitter.com/prashanthsams",
54 | "author_icon": "https://avatars3.githubusercontent.com/u/2948696?s=460&v=4",
55 | "title": "Your App - Android",
56 | "title_link": "https://twitter.com/prashanthsams",
57 | "text": f"{text}",
58 | "fields": [
59 | {
60 | "title": f"AE => :white_check_mark: {str(passed)} Passed :exclamation: {str(failed)} Failed",
61 | # "value": "3",
62 | "short": False
63 | },
64 | {
65 | "title": f"SA => :white_check_mark: {str(passed)} Passed :exclamation: {str(failed)} Failed",
66 | "short": False
67 | }
68 | ],
69 | "image_url": "http://my-website.com/path/to/image.jpg",
70 | "thumb_url": "http://example.com/path/to/thumb.png",
71 | "footer": "Appium Framework",
72 | "footer_icon": "https://platform.slack-edge.com/img/default_application_icon.png",
73 | "ts": int(datetime.datetime.now().strftime("%s"))
74 | }
75 | ]
76 | }
77 | requests.post(web_hook_url, data=json.dumps(slack_msg))
78 |
79 |
80 | def quote():
81 | quotes = [
82 | "Tests without assertions are not tests - Prashanth Sams",
83 | "In God we Trust for the rest we Test"
84 | ]
85 | return random.choice(quotes)
86 |
87 |
88 | def status_count(json_object, status):
89 | try:
90 | return json_object['report']['summary'][f'{status}']
91 | except KeyError as e:
92 | try:
93 | return json_object['data'][0]['attributes']['summary'][f'{status}']
94 | except KeyError as e:
95 | return 0
96 |
97 |
98 | class dotdict(dict):
99 | __getattr__ = dict.get
100 | __setattr__ = dict.__setitem__
101 | __delattr__ = dict.__delitem__
--------------------------------------------------------------------------------
/src/helpers/constants.py:
--------------------------------------------------------------------------------
1 | EN = {
2 | 'USERNAME': 'value',
3 | 'PASSWORD': 'value'
4 | }
5 |
6 | AR = {
7 | 'USERNAME': 'vallue',
8 | 'PASSWORD': 'value'
9 | }
--------------------------------------------------------------------------------
/src/screens/android/base_screen.py:
--------------------------------------------------------------------------------
1 | from appium.webdriver.common.mobileby import MobileBy
2 | from src.helpers.appiumdriver import Driver
3 |
4 |
5 | class BaseScreen(Driver):
6 | """
7 | common screen locators
8 | """
9 |
10 | def __init__(self, driver):
11 | super().__init__(driver)
--------------------------------------------------------------------------------
/src/screens/android/home_screen.py:
--------------------------------------------------------------------------------
1 | from appium.webdriver.common.mobileby import MobileBy
2 | from src.helpers.appiumdriver import Driver
3 |
4 |
5 | class HomeScreen(Driver):
6 | """
7 | home screen locators
8 | """
9 | loginMenu = (MobileBy.XPATH, "//android.view.ViewGroup[@content-desc='Login']/android.widget.TextView")
10 | formsMenu = (MobileBy.ACCESSIBILITY_ID, "Forms")
11 | homeMenu = (MobileBy.ACCESSIBILITY_ID, "Home")
12 | swipeMenu = (MobileBy.ACCESSIBILITY_ID, "Swipe")
13 | supportLink = (MobileBy.XPATH, '//android.widget.ScrollView[@content-desc="Home-screen"]/android.view.ViewGroup/android.view.ViewGroup[2]/android.widget.TextView[3]')
14 |
15 | # swipeMenu = {'ANDROID': (MobileBy.ACCESSIBILITY_ID, "Swipe"),'IOS': (MobileBy.ACCESSIBILITY_ID, "Swipe")}
16 |
17 | def __init__(self, driver):
18 | super().__init__(driver)
--------------------------------------------------------------------------------
/src/screens/android/login_screen.py:
--------------------------------------------------------------------------------
1 | from appium.webdriver.common.mobileby import MobileBy
2 | from src.helpers.appiumdriver import Driver
3 |
4 |
5 | class LoginScreen(Driver):
6 | """
7 | login screen locators
8 | """
9 | inputField = (MobileBy.XPATH, '//android.widget.EditText[@content-desc="input-email"]')
10 | passwordField = (MobileBy.ACCESSIBILITY_ID, 'input-password')
11 | loginButton = (MobileBy.XPATH, '//android.view.ViewGroup[@content-desc="button-LOGIN"]/android.view.ViewGroup')
12 |
13 | def __init__(self, driver):
14 | super().__init__(driver)
--------------------------------------------------------------------------------
/src/screens/ios/base_screen.py:
--------------------------------------------------------------------------------
1 | from appium.webdriver.common.mobileby import MobileBy
2 | from src.helpers.appiumdriver import Driver
3 |
4 |
5 | class BaseScreen(Driver):
6 | """
7 | common screen locators
8 | """
9 |
10 | def __init__(self, driver):
11 | super().__init__(driver)
--------------------------------------------------------------------------------
/src/screens/ios/home_screen.py:
--------------------------------------------------------------------------------
1 | from appium.webdriver.common.mobileby import MobileBy
2 | from src.helpers.appiumdriver import Driver
3 |
4 |
5 | class HomeScreen(Driver):
6 | """
7 | home screen locators
8 | """
9 | loginMenu = (MobileBy.ID, "Login")
10 | formsMenu = (MobileBy.ID, "Forms")
11 | homeMenu = (MobileBy.ID, "Home")
12 | swipeMenu = (MobileBy.ID, "Swipe")
13 |
14 | # swipeMenu = {'ANDROID': (MobileBy.ACCESSIBILITY_ID, "Swipe"),'IOS': (MobileBy.ACCESSIBILITY_ID, "Swipe")}
15 |
16 | def __init__(self, driver):
17 | super().__init__(driver)
--------------------------------------------------------------------------------
/src/screens/ios/login_screen.py:
--------------------------------------------------------------------------------
1 | from appium.webdriver.common.mobileby import MobileBy
2 | from src.helpers.appiumdriver import Driver
3 |
4 |
5 | class LoginScreen(Driver):
6 | """
7 | login screen locators
8 | """
9 | inputField = (MobileBy.ACCESSIBILITY_ID, 'input-email')
10 | passwordField = (MobileBy.ACCESSIBILITY_ID, 'input-password')
11 | loginButton = (MobileBy.XPATH, '//XCUIElementTypeStaticText[@name="LOGIN"]')
12 |
13 | def __init__(self, driver):
14 | super().__init__(driver)
--------------------------------------------------------------------------------
/src/spec/android/home_test.py:
--------------------------------------------------------------------------------
1 | import pytest
2 | from src.helpers.appiumdriver import Driver
3 | from src.screens.android.home_screen import HomeScreen
4 | from src.helpers.app import App
5 |
6 |
7 | class TestHome(Driver):
8 |
9 | def __init__(self, driver):
10 | super().__init__(driver)
11 |
12 | @pytest.mark.home
13 | def test_home_1(self):
14 | App.element(self, HomeScreen.homeMenu)
15 | App.element(self, HomeScreen.loginMenu)
16 | App.element(self, HomeScreen.formsMenu)
17 | App.element(self, HomeScreen.swipeMenu)
18 | App.swipe_until(self, HomeScreen.supportLink, start_x=144, start_y=434)
19 | # App.assert_text(self, HomeLocators.loginMenu, 'Leads')
20 |
21 | @pytest.mark.home
22 | def test_home_2(self):
23 | App.element(self, HomeScreen.homeMenu)
24 | App.element(self, HomeScreen.loginMenu)
--------------------------------------------------------------------------------
/src/spec/android/login_test.py:
--------------------------------------------------------------------------------
1 | import pytest
2 | from src.helpers.appiumdriver import Driver
3 | from src.screens.android.home_screen import HomeScreen
4 | from src.screens.android.login_screen import LoginScreen
5 | from src.helpers.app import App
6 |
7 |
8 | class TestLogin(Driver):
9 |
10 | def __init__(self, driver):
11 | super().__init__(driver)
12 |
13 | @pytest.mark.login
14 | def test_login(self):
15 | App.click(self, HomeScreen.loginMenu)
16 | App.send_keys(self, LoginScreen.inputField, "johnsmith@gmail.com")
17 | App.send_keys(self, LoginScreen.passwordField, "password", index=0)
18 | App.tap(self, LoginScreen.inputField)
--------------------------------------------------------------------------------
/src/spec/ios/home_test.py:
--------------------------------------------------------------------------------
1 | import pytest
2 | from src.helpers.appiumdriver import Driver
3 | from src.screens.ios.home_screen import HomeScreen
4 | from src.helpers.app import App
5 |
6 |
7 | class TestHome(Driver):
8 |
9 | def __init__(self, driver):
10 | super().__init__(driver)
11 |
12 | @pytest.mark.home
13 | def test_home_1(self):
14 | App.is_displayed(self, HomeScreen.homeMenu, True)
15 | App.is_displayed(self, HomeScreen.loginMenu, True)
16 | App.is_displayed(self, HomeScreen.formsMenu, True)
17 | App.is_displayed(self, HomeScreen.swipeMenu, True)
18 |
19 | @pytest.mark.home
20 | def test_home_2(self):
21 | App.is_displayed(self, HomeScreen.homeMenu, True)
22 | App.is_displayed(self, HomeScreen.loginMenu, True)
--------------------------------------------------------------------------------
/src/spec/ios/login_test.py:
--------------------------------------------------------------------------------
1 | import pytest
2 | from src.helpers.appiumdriver import Driver
3 | from src.screens.ios.home_screen import HomeScreen
4 | from src.screens.ios.login_screen import LoginScreen
5 | from src.helpers.app import App
6 |
7 |
8 | class TestLogin(Driver):
9 |
10 | def __init__(self, driver):
11 | super().__init__(driver)
12 |
13 | @pytest.mark.login
14 | def test_login(self):
15 | App.click(self, HomeScreen.loginMenu)
16 | App.send_keys(self, LoginScreen.inputField, "johnsmith@gmail.com")
17 | App.send_keys(self, LoginScreen.passwordField, "password", index=0)
18 | App.tap(self, LoginScreen.inputField)
--------------------------------------------------------------------------------
/tasks.py:
--------------------------------------------------------------------------------
1 | from src.helpers.business import notify_slack
2 | from invoke import task
3 | import os
4 |
5 |
6 | @task
7 | def test(c, env='staging', lang='en', app='android', device='emulator'):
8 | """
9 | update local storage
10 | Enable and modify this to add local storage
11 | """
12 | # os.system("adb push $(pwd)/data/.xml /data/data//shared_prefs")
13 | c.run(f'python3 -m pytest src/spec/{app}/*.py --app={app} --device={device}')
14 |
15 | @task
16 | def slack(c, env='staging', country='AE', slack='on', app='android'):
17 | if slack == 'on': notify_slack()
18 |
--------------------------------------------------------------------------------