8

I have seen about 100 touch event examples for the Java webdriver online, but not a single one for python. Would someone be so kind as to post one here, so it saves people many hours of search? Here is my attempt to do a basic double_tap on an element in an android simulator in order to zoom in on it. Much thanks

EDIT: Thanks to Julian's help I was able to figure out the missing link: for some reason, the touch actions require an extra .perform() at the end. Below you will find a bunch of touch events in action--and the code is cleaner. Enjoy!

import unittest, time
from selenium import webdriver

print "Here are our available touch actions (ignore the ones that look like __xx__): ", dir(webdriver.TouchActions)
#print dir(webdriver)



class Test(unittest.TestCase):


    def setUp(self):
        self.driver = webdriver.Remote(command_executor='http://localhost:8080/wd/hub',  desired_capabilities=webdriver.DesiredCapabilities.ANDROID)
        self.touch =webdriver.TouchActions(self.driver)

        #self.driver = TouchActions(self.driver)
        #self.driver = webdriver.Firefox()
        self.driver.implicitly_wait(30)


    def testHotmail(self):
        self.driver.get("http://www.hotmail.com")

        elem=self.driver.find_element_by_css_selector("input[name='login']")
        #tap command
        self.touch.tap(elem).perform()
        time.sleep(2)
        elem.send_keys("hello world")
        time.sleep(2)
        #double tap
        self.touch.double_tap(elem).perform()
        time.sleep(2)

        #testing that regular webdriver commands still work
        print self.driver.find_element_by_partial_link_text("Can't access").text

        elem= self.driver.find_element_by_css_selector("input[type='submit']")
        self.touch.tap(elem).perform()
        time.sleep(3)




    def tearDown(self):

        time.sleep(3)

        try:
            self.driver.quit()
        except Exception:
            print(" TearDown Method: Browser seems already closed.")

        pass


if __name__ == "__main__":
    unittest.main()

Here is an original Java Example:

WebElement toFlick = driver.findElement(By.id("image"));
// 400 pixels left at normal speed
Action flick = getBuilder(driver).flick(toFlick, 0, -400, FlickAction.SPEED_NORMAL)
        .build();
flick.perform();
WebElement secondImage = driver.findElement(“secondImage”);
assertTrue(secondImage.isDisplayed());

2 Answers 2

5

I've made some tweaks to your example, at least the test runs without error. I don't know what you expect the web site to do when a user double-taps in the username field...

Here is the revised code:

import unittest, time

from selenium.webdriver import Remote
from selenium.webdriver import  DesiredCapabilities
from selenium.webdriver.remote import webelement , command
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.touch_actions import TouchActions




class Test(unittest.TestCase):


    def setUp(self):
        remote = Remote(command_executor='http://localhost:8080/wd/hub',  desired_capabilities=DesiredCapabilities.ANDROID)
        self.remote=remote
        remote.implicitly_wait(30)

    def tearDown(self):
        pass


    def testName(self):
        # self.remote.get("http://icd.intraxinc.com/pxr")
        self.remote.get("https://icd.intraxinc.com/pxr/ext/login.action")
        elems= self.remote.find_element_by_css_selector("#j_username")
        print dir(self)
        print dir(self.remote)
        touchactions = TouchActions(self.remote)
        print dir(touchactions)
        touchactions.double_tap(elems)


if __name__ == "__main__":
    #import sys;sys.argv = ['', 'Test.testName']
    unittest.main()

I left various debug print statements in the example to show you how I investigated the problem you were facing. I also changed the URL to the one your login page redirects to. This was a workaround for an unrelated problem I had with a version of the Android driver, installed on the device.

FYI: I tested with android-server-2.21.0.apk on an Android phone running 4.0.4 of Android. Here are the material changes to your example code

        touchactions = TouchActions(self.remote)
        print dir(touchactions)
        touchactions.double_tap(elems)
Sign up to request clarification or add additional context in comments.

7 Comments

This was very helpful. Please see my original question for working code for Android webdriver. Woohoo!
Side question: In the webdriver init file, it already imports: from common.touch_actions import TouchActions . Why do we need to import touch Actions again in the test module?
Thanks for this extra question :) I learned something new from it. We don't need to import TouchActions if we import webdriver instead. It's available as part of the webdriver object e.g. webdriver.TouchActions(...) However because your code imports Remote and DesiredCapabilities separately it seems TouchActions is not in the imported namespace. from selenium import webdriver then try dir(webdriver.TouchActions) to see the methods. FYI compare cat py/selenium/webdriver/remote/__init__.py with cat py/selenium/webdriver/__init__.py
why do you need to import action chains if you only use touch actions?
@AkinHwan Good question about the import of ActionChains, I don't know if it's needed or not, I wrote this answer 6 years ago and the code was good enough to help the person who asked the question. I'm not actively working in this area. Feel free to experiment and update the answer based on your test results. For your other question, I've no idea if there's a suitable question - if you can't find one then how about asking a fresh question on StackOverflow?
|
2

You can also use mobile emulation to make touch actions work with selenium:

from selenium import webdriver
from selenium.webdriver.chrome.options import Options

mobile_emulation = { "deviceName": "Nexus 5" }

chrome_options = Options()
chrome_options.add_experimental_option("mobileEmulation", mobile_emulation)

driver = webdriver.Chrome(chrome_options = chrome_options)

Then use in the usual manner:

from selenium.webdriver import TouchActions

driver.get("http://example.com/")

element = context._selenium_browser.find_element_by_link_text("More information...")

touch_actions = TouchActions(driver)
touch_actions.tap(element).perform()

driver.current_url  # yields: https://www.iana.org/domains/reserved

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.