Skip to content

Commit b797254

Browse files
authored
Support for log_event and get_events command (appium#469)
* Use appium/events as endpoint to get events * Removed unnecessary codes * Update unittest along to changes * Update docstring * Created LogEvents class * Support log_event * Add unittest for log_event * Add functional test for log_event and get_event * review comments * Restore events API * Add type as arg to get_events * tweak * Removed type arg from get_events It isn't implemented yet for now * Add type arg to get_event The value isn't passed to the server for now. * Updated along to type
1 parent f955fb9 commit b797254

6 files changed

Lines changed: 192 additions & 5 deletions

File tree

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
#!/usr/bin/env python
2+
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
from selenium import webdriver
16+
17+
from ..mobilecommand import MobileCommand as Command
18+
19+
20+
class LogEvent(webdriver.Remote):
21+
22+
def get_events(self, type=None):
23+
""" Retrieves events information from the current session
24+
(Since Appium 1.16.0)
25+
26+
Args:
27+
type (:obj:`list` of :obj:`str`): The event type to filter with
28+
29+
Usage:
30+
events = driver.get_events()
31+
events = driver.get_events(['appium:funEvent'])
32+
33+
Returns:
34+
`dict`: A dictionary of events timing information containing the following entries
35+
commands: (`list` of `dict`) List of dictionaries containing the following entries
36+
cmd: (str) The command name that has been sent to the appium server
37+
startTime: (int) Received time
38+
endTime: (init) Response time
39+
"""
40+
data = {}
41+
if type is not None:
42+
data['type'] = type
43+
return self.execute(Command.GET_EVENTS, data)['value']
44+
45+
def log_event(self, vendor, event):
46+
"""Log a custom event on the Appium server.
47+
(Since Appium 1.16.0)
48+
49+
Args:
50+
vendor (str): The vendor to log
51+
event (str): The event to log
52+
53+
Usage:
54+
driver.log_event('appium', 'funEvent')
55+
56+
Returns:
57+
`appium.webdriver.webdriver.WebDriver`
58+
"""
59+
data = {
60+
'vendor': vendor,
61+
'event': event
62+
}
63+
self.execute(Command.LOG_EVENT, data)
64+
return self
65+
66+
# pylint: disable=protected-access
67+
68+
def _addCommands(self):
69+
self.command_executor._commands[Command.GET_EVENTS] = \
70+
('POST', '/session/$sessionId/appium/events')
71+
self.command_executor._commands[Command.LOG_EVENT] = \
72+
('POST', '/session/$sessionId/appium/log_event')

appium/webdriver/mobilecommand.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,9 @@ class MobileCommand(object):
7777

7878
EXECUTE_DRIVER = 'executeDriver'
7979

80+
GET_EVENTS = 'getLogEvents'
81+
LOG_EVENT = 'logCustomEvent'
82+
8083
# Android
8184
OPEN_NOTIFICATIONS = 'openNotifications'
8285
START_ACTIVITY = 'startActivity'

appium/webdriver/webdriver.py

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
from .extensions.ime import IME
4747
from .extensions.keyboard import Keyboard
4848
from .extensions.location import Location
49+
from .extensions.log_event import LogEvent
4950
from .extensions.remote_fs import RemoteFS
5051
from .extensions.screen_record import ScreenRecord
5152
from .extensions.search_context import AppiumSearchContext
@@ -125,6 +126,7 @@ class WebDriver(
125126
IME,
126127
Keyboard,
127128
Location,
129+
LogEvent,
128130
Network,
129131
Performance,
130132
Power,
@@ -368,7 +370,7 @@ def battery_info(self):
368370
"""Retrieves battery information for the device under test.
369371
370372
Returns:
371-
A dictionary containing the following entries
373+
`dict`: containing the following entries
372374
level: Battery level in range [0.0, 1.0], where 1.0 means 100% charge.
373375
Any value lower than 0 means the level cannot be retrieved
374376
state: Platform-dependent battery state value.
@@ -389,31 +391,38 @@ def battery_info(self):
389391
@property
390392
def session(self):
391393
""" Retrieves session information from the current session
394+
392395
Usage:
393396
session = driver.session
397+
394398
Returns:
395-
`dict containing information from the current session`
399+
`dict`: containing information from the current session
396400
"""
397401
return self.execute(Command.GET_SESSION)['value']
398402

399403
@property
400404
def all_sessions(self):
401405
""" Retrieves all sessions that are open
406+
402407
Usage:
403408
sessions = driver.all_sessions
409+
404410
Returns:
405-
`dict containing all open sessions`
411+
`dict`: containing all open sessions
406412
"""
407413
return self.execute(Command.GET_ALL_SESSIONS)['value']
408414

415+
# pylint: disable=protected-access
416+
409417
@property
410418
def events(self):
411419
""" Retrieves events information from the current session
420+
412421
Usage:
413422
events = driver.events
414423
415424
Returns:
416-
`dict containing events timing information from the current session`
425+
`dict`: containing events timing information from the current session
417426
"""
418427
try:
419428
session = self.session

ci-jobs/functional_test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,6 @@ jobs:
8585
name: 'func_test_android8'
8686
vmImage: ${{ parameters.vmImage }}
8787
pytestOpt: ${{ parameters.pytestOpt }}
88-
testFiles: 'network_connection_tests.py'
88+
testFiles: 'network_connection_tests.py log_event_tests.py'
8989
sdkVer: ${{ parameters.androidSdkVer }}
9090
CI: ${{ parameters.ci }}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#!/usr/bin/env python
2+
# -*- coding: utf-8 -*-
3+
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
16+
import unittest
17+
18+
from .helper.test_helper import BaseTestCase
19+
20+
21+
class LogEventTests(BaseTestCase):
22+
def test_log_event(self):
23+
vendor = 'appium'
24+
event = 'funEvent'
25+
self.driver.log_event(vendor, event)
26+
assert '{}:{}'.format(vendor, event) in self.driver.get_events().keys()
27+
28+
29+
if __name__ == '__main__':
30+
suite = unittest.TestLoader().loadTestsFromTestCase(LogEventTests)
31+
unittest.TextTestRunner(verbosity=2).run(suite)
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
#!/usr/bin/env python
2+
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
import json
16+
17+
import httpretty
18+
19+
from appium.webdriver.webdriver import WebDriver
20+
from test.unit.helper.test_helper import (
21+
appium_command,
22+
get_httpretty_request_body,
23+
ios_w3c_driver
24+
)
25+
26+
27+
class TestWebDriverLogEvents(object):
28+
29+
@httpretty.activate
30+
def test_get_events(self):
31+
driver = ios_w3c_driver()
32+
httpretty.register_uri(
33+
httpretty.POST,
34+
appium_command('/session/1234567890/appium/events'),
35+
body=json.dumps({'value': {'appium:funEvent': [12347]}})
36+
)
37+
events = driver.get_events()
38+
assert events['appium:funEvent'] == [12347]
39+
40+
d = get_httpretty_request_body(httpretty.last_request())
41+
assert 'type' not in d.keys()
42+
43+
@httpretty.activate
44+
def test_get_events_args(self):
45+
driver = ios_w3c_driver()
46+
httpretty.register_uri(
47+
httpretty.POST,
48+
appium_command('/session/1234567890/appium/events'),
49+
body=json.dumps({'value': {'appium:funEvent': [12347]}})
50+
)
51+
events_to_filter = ['appium:funEvent']
52+
events = driver.get_events(events_to_filter)
53+
assert events['appium:funEvent'] == [12347]
54+
55+
d = get_httpretty_request_body(httpretty.last_request())
56+
assert d['type'] == events_to_filter
57+
58+
@httpretty.activate
59+
def test_log_event(self):
60+
driver = ios_w3c_driver()
61+
httpretty.register_uri(
62+
httpretty.POST,
63+
appium_command('/session/1234567890/appium/log_event'),
64+
body=""
65+
)
66+
vendor_name = 'appium'
67+
event_name = 'funEvent'
68+
assert isinstance(driver.log_event(vendor_name, event_name), WebDriver)
69+
70+
d = get_httpretty_request_body(httpretty.last_request())
71+
assert d['vendor'] == vendor_name
72+
assert d['event'] == event_name

0 commit comments

Comments
 (0)