Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
language: python
dist: xenial

python:
- "2.7"
- "3.4"
- "3.5"
- "3.6"
- "3.7"

install:
- pip install -r ci-requirements.txt
Expand Down
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,24 @@ download and unarchive the source tarball (Appium-Python-Client-X.X.tar.gz).
```
- You can customise `CHANGELOG.rst` with commit messages following [.gitchangelog.rc](.gitchangelog.rc)
- It generates readable changelog
- `pip install -r development.txt`

## Run tests

### Unit

```
$ py.test test/unit
```

Run with `pytest-xdist`

```
$ py.test -n 2 test/unit
```

### Functional

```
$ py.test test/functional/ios/find_by_ios_class_chain_tests.py
```
Expand Down
1 change: 1 addition & 0 deletions ci-requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ astroid==1.6.5
isort==4.3.4
pylint==1.9.3
autopep8==1.4.3
httpretty==0.9.6
2 changes: 1 addition & 1 deletion ci.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ if [[ $result ]] ; then
fi

python -m pylint --rcfile .pylintrc appium test --py3k
python -m pytest test/unit/*
python -m pytest test/unit/
1 change: 1 addition & 0 deletions development.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
-r ci-requirements.txt
13 changes: 13 additions & 0 deletions test/unit/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#!/usr/bin/env python

# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
13 changes: 13 additions & 0 deletions test/unit/helper/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#!/usr/bin/env python

# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
77 changes: 77 additions & 0 deletions test/unit/helper/test_helper.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
#!/usr/bin/env python

# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import unittest
import httpretty
import json

from appium import webdriver


class TestHelper():

@staticmethod
def mock_android_driver():
"""
Return a driver which is generated a mock response

:return: An instance of WebDriver
:rtype: WebDriver
"""

response_body_json = json.dumps(
{
'value': {
'sessionId': '1234567890',
'capabilities': {
'platform': 'LINUX',
'desired': {
'platformName': 'Android',
'automationName': 'uiautomator2',
'platformVersion': '7.1.1',
'deviceName': 'Android Emulator',
'app': '/test/apps/ApiDemos-debug.apk',
},
'platformName': 'Android',
'automationName': 'uiautomator2',
'platformVersion': '7.1.1',
'deviceName': 'emulator-5554',
'app': '/test/apps/ApiDemos-debug.apk',
'deviceUDID': 'emulator-5554',
'appPackage': 'com.example.android.apis',
'appWaitPackage': 'com.example.android.apis',
'appActivity': 'com.example.android.apis.ApiDemos',
'appWaitActivity': 'com.example.android.apis.ApiDemos'
}
}
}
)

httpretty.register_uri(
httpretty.POST,
'http://localhost:4723/wd/hub/session',
body=response_body_json
)

desired_caps = {
'platformName': 'Android',
'deviceName': 'Android Emulator',
'app': 'path/to/app',
'automationName': 'UIAutomator2'
}
driver = webdriver.Remote(
'http://localhost:4723/wd/hub',
desired_caps
)
return driver
35 changes: 35 additions & 0 deletions test/unit/webdriver/device/clipboard_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#!/usr/bin/env python

# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from test.unit.helper.test_helper import TestHelper

import json
import httpretty


class TestWebDriverDeviceClipboard(object):

@httpretty.activate
def test_clipboard(self):
driver = TestHelper.mock_android_driver()
httpretty.register_uri(
httpretty.POST,
'http://localhost:4723/wd/hub/session/1234567890/appium/device/set_clipboard',
body='{"value": ""}'
)
driver.set_clipboard_text('hello')

d = json.loads(httpretty.last_request().body.decode('utf-8'))
assert d['content'] == 'aGVsbG8='
assert d['contentType'] == 'plaintext'
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,17 @@
# See the License for the specific language governing permissions and
# limitations under the License.

import unittest

import pytest
from appium.webdriver.common.multi_action import MultiAction
from appium.webdriver.common.touch_action import TouchAction


class MultiActionTests(unittest.TestCase):
def setUp(self):
self._multi_action = MultiAction(DriverStub())
class TestMultiAction(object):
@pytest.fixture
def multi_action(self):
return MultiAction(DriverStub())

def test_json(self):
self.maxDiff = None
def test_json(self, multi_action):
json = {
'actions': [
[
Expand All @@ -40,23 +39,19 @@ def test_json(self):
}
t1 = TouchAction(DriverStub()).press(ElementStub(1)).move_to(x=10, y=20).release()
t2 = TouchAction(DriverStub()).press(ElementStub(5), 11, 30).move_to(x=12, y=-300).release()
self._multi_action.add(t1, t2)
self.assertEqual(json, self._multi_action.json_wire_gestures)
multi_action.add(t1, t2)
assert json == multi_action.json_wire_gestures


class DriverStub(object):
def execute(self, action, params):
def execute(self, _action, _params):
print("driver.execute called")


class ElementStub(object):
def __init__(self, id):
self._id = id
def __init__(self, e_id):
self._id = e_id

@property
def id(self):
return self._id


if __name__ == "__main__":
unittest.main()
Original file line number Diff line number Diff line change
Expand Up @@ -12,43 +12,41 @@
# See the License for the specific language governing permissions and
# limitations under the License.

import unittest
import pytest

from appium.webdriver.common.touch_action import TouchAction


class TouchActionTests(unittest.TestCase):
def setUp(self):
self._touch_action = TouchAction(DriverStub())
class TestTouchAction(object):

def test_tap_json(self):
@pytest.fixture
def touch_action(self):
return TouchAction(DriverStub())

def test_tap_json(self, touch_action):
json = [
{'action': 'tap', 'options': {'count': 1, 'element': 1}}
]
self._touch_action.tap(ElementStub(1))
self.assertEqual(json, self._touch_action.json_wire_gestures)
touch_action.tap(ElementStub(1))
assert json == touch_action.json_wire_gestures

def test_tap_x_y_json(self):
def test_tap_x_y_json(self, touch_action):
json = [
{'action': 'tap', 'options': {'x': 3, 'y': 4, 'count': 1, 'element': 2}}
]
self._touch_action.tap(ElementStub(2), 3, 4)
self.assertEqual(json, self._touch_action.json_wire_gestures)
touch_action.tap(ElementStub(2), 3, 4)
assert json == touch_action.json_wire_gestures


class DriverStub(object):
def execute(self, action, params):
def execute(self, _action, _params):
print("driver.execute called")


class ElementStub(object):
def __init__(self, id, x=None, y=None, count=None):
self._id = id
def __init__(self, e_id, _x=None, _y=None, _count=None):
self._id = e_id

@property
def id(self):
return self._id


if __name__ == "__main__":
unittest.main()
84 changes: 84 additions & 0 deletions test/unit/webdriver/webdriver_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
#!/usr/bin/env python

# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import json
import httpretty

from appium import webdriver


class TestWebDriverWebDriver(object):

@httpretty.activate
def test_create_session(self):
httpretty.register_uri(
httpretty.POST,
'http://localhost:4723/wd/hub/session',
body='{ "value": { "sessionId": "session-id", "capabilities": {"deviceName": "Android Emulator"}}}'
)

desired_caps = {
'platformName': 'Android',
'deviceName': 'Android Emulator',
'app': 'path/to/app',
'automationName': 'UIAutomator2'
}
driver = webdriver.Remote(
'http://localhost:4723/wd/hub',
desired_caps
)

assert len(httpretty.HTTPretty.latest_requests) == 1

request = httpretty.HTTPretty.latest_requests[0]
assert request.headers['content-type'] == 'application/json;charset=UTF-8'

request_json = json.loads(httpretty.HTTPretty.latest_requests[0].body.decode('utf-8'))
assert request_json.get('capabilities') is not None
assert request_json.get('desiredCapabilities') is not None

assert driver.session_id == 'session-id'
assert driver.w3c

@httpretty.activate
def test_create_session_forceMjsonwp(self):
httpretty.register_uri(
httpretty.POST,
'http://localhost:4723/wd/hub/session',
body='{ "capabilities": {"deviceName": "Android Emulator"}, "status": 0, "sessionId": "session-id"}'
)

desired_caps = {
'platformName': 'Android',
'deviceName': 'Android Emulator',
'app': 'path/to/app',
'automationName': 'UIAutomator2',
'forceMjsonwp': True
}
driver = webdriver.Remote(
'http://localhost:4723/wd/hub',
desired_caps
)

assert len(httpretty.HTTPretty.latest_requests) == 1

request = httpretty.HTTPretty.latest_requests[0]
assert request.headers['content-type'] == 'application/json;charset=UTF-8'

request_json = json.loads(httpretty.HTTPretty.latest_requests[0].body.decode('utf-8'))
assert request_json.get('capabilities') is None
assert request_json.get('desiredCapabilities') is not None

assert driver.session_id == 'session-id'
assert driver.w3c is False