| #!/usr/bin/env python |
| # |
| # Copyright 2017 Google Inc. All Rights Reserved. |
| # |
| # 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. |
| """Simple script for Webdriver Wire Protocol communication.""" |
| |
| import binascii |
| import json |
| import time |
| import requests |
| |
| # This is a simple script for Webdriver Wire Protocol communication. |
| # https://github.com/SeleniumHQ/selenium/wiki/JsonWireProtocol |
| |
| WEBDRIVER_HOST = 'http://localhost:4444' |
| |
| GET = 'GET' |
| POST = 'POST' |
| DELETE = 'DELETE' |
| |
| |
| def Request(request_type, path='', parameters=None): |
| """Perform a WebDriver JSON Wire Protocol Request. |
| |
| Args: |
| request_type: GET, POST, or DELETE |
| path: optional path string for the request |
| parameters: optional parameter dictionary for the request |
| |
| Returns: |
| The dictionary returned by the WebDriver server |
| """ |
| url = '%s/%s' % (WEBDRIVER_HOST, path) |
| headers = {'content-type': 'application/json', 'Accept-Charset': 'UTF-8'} |
| if request_type == GET: |
| request = requests.get(url, data=json.dumps(parameters), headers=headers) |
| if request_type == POST: |
| request = requests.post(url, data=json.dumps(parameters), headers=headers) |
| if request_type == DELETE: |
| request = requests.delete(url, data=json.dumps(parameters), headers=headers) |
| result = request.text if request.headers[ |
| 'content-type'] == 'text/plain' else request.json() |
| if request.status_code == 200: |
| return result |
| else: |
| print '*** Error %d: %s' % (request.status_code, result['value']['message'] |
| if isinstance(result, dict) else result) |
| return None |
| |
| |
| def SessionRequest(session_id, request_type, path=None, parameters=None): |
| """Perform a WebDriver JSON Wire Protocol Session Request. |
| |
| Args: |
| session_id: Value for ':sessionId' for the request |
| request_type: GET, POST, or DELETE |
| path: optional path string for the request |
| parameters: optional parameter dictionary for the request |
| |
| Returns: |
| The dictionary returned by the WebDriver server |
| """ |
| if path: |
| return Request(request_type, 'session/%s/%s' % (session_id, path), |
| parameters) |
| return Request(request_type, 'session/%s' % (session_id), parameters) |
| |
| |
| def ElementRequest(session_id, |
| element_id, |
| request_type, |
| path=None, |
| parameters=None): |
| return SessionRequest(session_id, request_type, 'element/%s/%s' % |
| (element_id[u'ELEMENT'], path), parameters) |
| |
| |
| def GetSessionID(): |
| """Retrieve a WebDriver JSON Wire Protocol Session. |
| |
| Returns: |
| The value for ':sessionId' to be used for Session Requests |
| """ |
| request = Request(POST, 'session', {'desiredCapabilities': {}}) |
| if request: |
| session_id = request[u'sessionId'] |
| else: |
| # If creating a new session id fails, use an already existing session. |
| request = Request(GET, 'sessions') |
| if request: |
| session_id = request['value'][0] |
| return session_id |
| |
| |
| def DeleteSession(session_id): |
| """Delete a WebDriver JSON Wire Protocol Session. |
| |
| Args: |
| session_id: Value for ':sessionId' for the request |
| |
| Returns: |
| The dictionary returned by the WebDriver server |
| """ |
| return SessionRequest(session_id, DELETE) |
| |
| |
| def GetScreenShot(session_id, filename): |
| """Retrieve a Screenshot. |
| |
| Args: |
| session_id: Value for ':sessionId' for the request |
| filename: The filename to write the PNG screenshot to |
| """ |
| request = SessionRequest(session_id, GET, 'screenshot') |
| if request: |
| with open(filename, 'w') as f: |
| f.write(binascii.a2b_base64(request['value'])) |
| f.close() |
| |
| |
| def GetActiveElement(session_id): |
| return SessionRequest(session_id, POST, 'element/active')['value'] |
| |
| |
| def Moveto(session_id, element, xoffset, yoffset): |
| return SessionRequest(session_id, POST, 'moveto', { |
| u'element': element, |
| u'xoffset': xoffset, |
| u'yoffset': yoffset |
| }) |
| |
| |
| def Click(session_id, button): |
| return SessionRequest(session_id, POST, 'click', {u'button': button}) |
| |
| |
| def Buttondown(session_id, button): |
| return SessionRequest(session_id, POST, 'buttondown', {u'button': button}) |
| |
| |
| def Buttonup(session_id, button): |
| return SessionRequest(session_id, POST, 'buttonup', {u'button': button}) |
| |
| |
| def ElementName(session_id, element_id): |
| return ElementRequest(session_id, element_id, GET, 'name') |
| |
| |
| def ElementText(session_id, element_id): |
| return ElementRequest(session_id, element_id, GET, 'text') |
| |
| |
| def ElementClick(session_id, element_id, button): |
| return ElementRequest(session_id, element_id, POST, 'click', |
| {u'button': button}) |
| |
| |
| def ElementKeys(session_id, element_id, keys): |
| return ElementRequest(session_id, element_id, POST, 'value', {u'value': keys}) |
| |
| |
| def ElementFind(session_id, using, value): |
| return SessionRequest(session_id, POST, 'element', |
| {u'using': using, |
| u'value': value})['value'] |
| |
| |
| def MouseTest(): |
| # Do a simple test that hovers the mouse to the right from the active |
| # element, then clicks on the element of class 'trending'. |
| session_id = GetSessionID() |
| active_element = GetActiveElement(session_id) |
| print 'active_element : %s' % active_element |
| |
| for xoffset in range(0, 1900, 20): |
| print 'Moveto: %s' % Moveto(session_id, active_element, xoffset, 200) |
| time.sleep(0.05) |
| |
| trending_element = ElementFind(session_id, 'class name', 'trending') |
| print 'trending_element : %s' % trending_element |
| |
| print 'ElementClick: %s' % ElementClick(session_id, trending_element, 0) |
| |
| DeleteSession(session_id) |
| |
| |
| def main(): |
| MouseTest() |
| |
| |
| if __name__ == '__main__': |
| main() |