diff --git a/README b/README deleted file mode 100644 index 9662f2f..0000000 --- a/README +++ /dev/null @@ -1,72 +0,0 @@ -============ -Introduction -============ - -:Author: Sean Wang - -AndroidWebDriver4Python is an add-on to Selenium Python Client Driver. -Its source code could be found from -http://code.google.com/p/selenium/source/browse/trunk/py - -As I could not find Android WebDriver implementation in it, -and I really like Python as opposed to Java. So I want to implement one. - -More infomation about Selenium, plz check http://code.google.com/p/selenium/ - -============ -Installing -============ - -As I am a newbie, I do not expect to commit in the Selenium project. -To install this AndroidDriver for Python, you need: -1. download and extract Python client from http://pypi.python.org/pypi/selenium#downloads -2. download AndroidWebDriver4Python from using git clone git://github.com/truebit/AndroidWebDriver4Python.git -4. copy the entire 'py' folder under AndroidWebDriver4Python to merge the -same one in root directory of AndroidDriver for Python -5. back to the root directory of Selenium Python Client, to install this -modified version using command: - python setup.py install - -Here you have installed this AndroidWebDriver4Python add-on. -There are some prerequisites to use AndroidWebDriver4Python. - -6. Install Android SDK and set 'tools' and 'platform-tools' in your PATH: -http://developer.android.com/sdk/installing.html - -7. Install Android server side application on your device: - Download android-server-2.x.x.apk from - http://code.google.com/p/selenium/downloads/list - -8. enable 'USB Debugging' in your device, which normally could found from: - Settings>Applications>Development>USB debugging - -9. connect USB cable between device and PC, install adb drivers - -For more information you could check -http://code.google.com/p/selenium/downloads/list,but you do not need to do all -those steps. Above 3 steps is all you need to do. - - -============ -Example -============ - -from selenium import webdriver - -driver= webdriver.Android() -#another way is to explicitly specify the serial id of the device -#driver=webdriver.Android('emulator-5554') -driver.get("http://www.symbio.com") -driver.quit() - -============ -Documentation -============ - -The latest Selenium Python documentation covers all So plz check latest documentation -at http://http://readthedocs.org/docs/selenium-python/en/latest - -Use The Source Luke! -==================== - -http://code.google.com/p/selenium/source/browse/trunk/py/selenium/webdriver/remote/webdriver.py diff --git a/README.md b/README.md new file mode 100644 index 0000000..0129d8d --- /dev/null +++ b/README.md @@ -0,0 +1,66 @@ +# Introduction + +_Author: Sean Wang xiao.wang@symbio.com_ + +AndroidWebDriver4Python is an addon to [Selenium Python Client Driver](http://pypi.python.org/pypi/selenium) + +This addon supports multiple real devices simultaneously from release 1.1, but not supports emulators. I have not figured out yet. + + +As I could not find Android WebDriver implementation in it,and I really like Python as opposed to Java. So I want to implement one. +I know that I am a newbie, I do not expect to commit in the Selenium project. + + +More infomation about *Selenium*, plz check http://code.google.com/p/selenium/ + +# Installing + +To install this AndroidDriver for Python, you need: + +1. download AndroidWebDriver4Python using command: + +``` +$ git clone git://github.com/truebit/AndroidWebDriver4Python.git +``` + +2. download and extract [Selenium Python client](http://pypi.python.org/pypi/selenium#downloads) +3. copy the entire `py` folder under AndroidWebDriver4Python to merge the +same one in root directory of AndroidDriver for Python +4. back to the root directory of Selenium Python Client, to install this modified version using command: + +``` +$ python setup.py install +``` + +Here you have installed this AndroidWebDriver4Python add-on. +There are some prerequisites to use AndroidWebDriver4Python. + +* [Install Android SDK](http://developer.android.com/sdk/installing.html) and set its `tools` and `platform-tools` in your PATH +* Install Android server side application [android-server-2.x.x.apk](http://code.google.com/p/selenium/downloads/list) on your device +* enable `USB Debugging` in your device and disable autolock, which normally could found from `Home>Settings>Applications>Development>USB debugging` + +* connect USB cable between device and PC, install adb drivers + +# Example +```python +from selenium import webdriver + +# if only one device connected, you do not need to specifiy the serial id. +# exmaple driver=webdriver.Android() +driver1= webdriver.Android('HT1234567') +driver2=webdriver.Android('091012345601E00D') +driver1.get("http://www.symbio.com") +driver2.get("http://www.google.com.hk") +driver1.quit() +driver2.quit() +``` + +If you want more detailed example, plz check [example.py](AndroidWebDriver4Python/blob/master/example/example.py) + +# Documentation + +The latest [Selenium Python Bindings documentation](http://readthedocs.org/docs/selenium-python/en/latest) + +# Use The Source Luke! + +As this Android Driver I implemented is herited from [webdriver.py](http://code.google.com/p/selenium/source/browse/trunk/py/selenium/webdriver/remote/webdriver.py), so plz see its source code to use Android driver just like other WebDriver. diff --git a/example/example.py b/example/example.py new file mode 100644 index 0000000..bab0e9e --- /dev/null +++ b/example/example.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +""" +@author: Sean Wang: xiao.wang@symbio.com + +This demo is written according to the two demos in selenium AndroidDriver wiki: + +http://code.google.com/p/selenium/wiki/AndroidDriver#Run_the_Tests +and +http://code.google.com/p/selenium/wiki/AndroidDriver#Using_the_Android_Test_Framework + +to demostrate that why I implement Selenium AndroidDriver for Python Client: +Python is so simple and elegant +""" + +import unittest +from selenium import webdriver + +class Test(unittest.TestCase): + + def setUp(self): + self.driver=webdriver.Android() + self.driver.implicitly_wait(30) + self.driver.get("http://www.google.com.hk") + + def tearDown(self): + self.driver.quit() + + def testDemo(self): + searchBox=self.driver.find_element_by_name('q') + searchBox.send_keys("Symbio") + searchBox.submit() + print "Page title is: %s"%self.driver.title + #Ensure the title contains "Google" + self.assertTrue("Google" in self.driver.title) + #Ensure that there is at least one link with the keyword "Symbio" + self.assertTrue(len(self.driver.find_elements_by_partial_link_text("Symbio"))>0) + +if __name__ == "__main__": + unittest.main() diff --git a/py/selenium/webdriver/android/service.py b/py/selenium/webdriver/android/service.py index 6654a5d..a192efa 100644 --- a/py/selenium/webdriver/android/service.py +++ b/py/selenium/webdriver/android/service.py @@ -30,7 +30,7 @@ class Service(object): ANDROID_DRIVER_CLIENT_APP_CMP= r'org.openqa.selenium.android.app/.MainActivity' - def __init__(self,device=None): + def __init__(self,device=None,port=0): """ Creates a new instance of the Service Args: device: serial ID of the Android device. @@ -39,6 +39,9 @@ def __init__(self,device=None): """ self.device= Service.initDevice(device) self.adbCmd= r'adb -s %s '%self.device + self.port = port + if self.port == 0: + self.port = utils.free_port() @staticmethod def initDevice(deviceID=None): @@ -46,13 +49,9 @@ def initDevice(deviceID=None): # as adb server launching process made the script stuck, # so I use hard-coded wait time to make it through # I do not know why subprocess could not get output in such situation - cmd1= 'adb kill-server' - cmd2= 'adb start-server' - cmd3= 'adb devices' - ret=subprocess.call(cmd1,stdout=PIPE, stderr=PIPE,shell=True) - if ret: - raise WebDriverException(Service.CMD_NOT_IN_PATH) - p=subprocess.Popen(cmd2,stdout=PIPE, stderr=PIPE,shell=True) + cmd1= 'adb start-server' + cmd2= 'adb devices' + p=subprocess.Popen(cmd1,stdout=PIPE, stderr=PIPE,shell=True) count=0 while count<30: time.sleep(1) @@ -60,28 +59,28 @@ def initDevice(deviceID=None): break else: raise WebDriverException("adb could not get device info after 30 seconds.") - output=subprocess.check_output(cmd3,shell=True).split()[4:] + output=subprocess.check_output(cmd2,shell=True).split()[4:] for i, v in enumerate(output): if i + 1 < len(output) and i % 2 == 0: deviceInfo.append((v, output[i + 1])) if deviceInfo: # check if all devices are online if 'device' not in [i[1] for i in deviceInfo]: - raise WebDriverException( """No device is good to go. + raise WebDriverException( """No device is online. Reconnect devices and retry. Only a deviceID followed with 'device' would work.""") if deviceID: # check if device with given deviceID is connected if deviceID in [i[0] for i in deviceInfo]: - print "Connected to %s..." % deviceID + #print "Connected to %s..." % deviceID return deviceID else: - raise WebDriverException("""No device with serial ID '%s' found. + raise WebDriverException("""Could not find device with serial id %r. Plz make sure you got the right ID."""%deviceID) else: for i in deviceInfo: if i[1] =='device': - print "Connected to %s..." % i[0] + #print "Connected to %s..." % i[0] return i[0] else: raise WebDriverException("""No devices found. @@ -93,16 +92,18 @@ def start(self): WebDriverException : Raised either when it can't start the service or when it can't connect to the service""" - print 'start tcp port 8080 forwarding' - subprocess.call('%s forward tcp:8080 tcp:8080'%self.adbCmd,shell=True) - print 'stop existing android server by sending back key' - # this is not mandatory as we already killed adb server, but could this + #print 'start tcp port 8080 forwarding' + subprocess.call(r'%s forward tcp:%d tcp:8080'%(self.adbCmd,self.port),shell=True) + + + # this is not mandatory as we already killed adb server, but this could # decrease the webview created in andriod server application. maybe # it's a bug to create one webview per launch of app? + #print 'stop existing android server by sending back key' for i in xrange(4): subprocess.call(r'%s shell input keyevent 4'%self.adbCmd,shell=True) - print 'start android server activity' + #print 'start android server activity' output=subprocess.check_output(r'%s shell am start -n %s'%(self.adbCmd, Service.ANDROID_DRIVER_CLIENT_APP_CMP), stderr=subprocess.STDOUT,shell=True).split() @@ -112,18 +113,19 @@ def start(self): http://code.google.com/p/selenium/downloads/list""") # wait for WebDriver Client to be launched completely time.sleep(2) + print "AndroidDriver started on device %s" % repr(self.device) @property def service_url(self): - """ Gets the url of the ChromeDriver Service """ - return "http://127.0.0.1:8080/wd/hub" + """ Gets the url of the AndroidDriver Service """ + return "http://127.0.0.1:%d/wd/hub"%self.port def stop(self): """ Close AndroidDriver by sending BACK keyevent to device""" try: print 'stopping AndroidDriver' subprocess.Popen(r'%s shell input keyevent 4'%self.adbCmd, - stdout=PIPE, stderr=PIPE) + stdout=PIPE, stderr=PIPE,shell=True) except: print """AndroidDriver was not closed. Close by yourself by tapping back key to exit AndroidDriver on device.""" diff --git a/py/selenium/webdriver/android/webdriver.py b/py/selenium/webdriver/android/webdriver.py index 8d117f7..7553bf2 100644 --- a/py/selenium/webdriver/android/webdriver.py +++ b/py/selenium/webdriver/android/webdriver.py @@ -1,3 +1,20 @@ +#!/usr/bin/python +# +# Copyright 2011 Webdriver_name committers +# Copyright Sean Wang : xiao.wang@symbio.com +# +# 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 selenium.webdriver.remote.webdriver import WebDriver as RemoteWebDriver from selenium.webdriver.common.desired_capabilities import DesiredCapabilities from selenium.webdriver.remote.command import Command @@ -5,8 +22,8 @@ class WebDriver(RemoteWebDriver): - def __init__(self,deviceID=None): - self.service = Service(deviceID) + def __init__(self,deviceID=None,port=0): + self.service = Service(deviceID,port=port) self.service.start() RemoteWebDriver.__init__(self, command_executor=self.service.service_url,