Appium multiple clicks no longer working - python

I updated appium to version 1.3.6 today and the portion of my tests where multiple clicks are used are no longer working. I basically have an element that I want to click three times, like I would a double-click.
This is the code that was working prior to the update:
some_element = self.driver.find_element_by_name('some_element')
some_element.click()
some_element.click()
some_element.click()
In attempts to figure out why this no longer works, I embedded print commands between the clicks and noticed that the three clicks aren't happening fast enough to be registered by the application.

I found the solution, instead of click use tap:
https://github.com/appium/python-client#tap
The wrong way:
some_element = self.driver.find_element_by_name('some_element')
some_element.click()
some_element.click()
some_element.click()
The right way:
(from appium.webdriver.common.touch_action import TouchAction)
some_element = self.driver.find_element_by_name('some_element')
triple_click = TouchAction(self.driver)
# the parameters for tap are element, x-offset, y-offset, and count
triple_click.tap(some_element, 0, 0, 3)

Put sleep command in between each click. I am sure this will fix the issue.

Related

How can I change the format of Python GTK3 SpinButton displayed text?

Basing my code on this allegedly Python-specific documentation example, I have:
def on_output(spin):
adj = spin.get_adjustment()
val = int(adj.get_value())
s = "%02d" % val
print "on_output: %s" % s
spin.set_text(s)
which I connect to my SpinButton's "output" signal. It seems to work when the control is first displayed (shows "00"), but when I click SpinButton's increment button, the formatted value from on_output is overwritten, so e.g. my "01" is shown as plain "1". Looks like another signal or event is causing the control to reformat itself after on_output, but I'm struggling a bit to diagnose. Any experts on GTK3 with Python, please help with debugging suggestions.
Platform is Xubuntu 18.10, Python 2.7, GTK3 3.22.
Wow! If ever there was a case for responding with 'RTFM!' this was it. As very politely pointed out by Alexander Dmitriev, the 'return' statement is missing. In my first attempt, I returned True, but it failed (for some presumably unrelated reason) so I tried False which made no difference. Somehow, the return value got lost after that, and when I re-read the doco 'carefully' I missed seeing it -- we see what we expect to see! I must be getting too old for this hacking game, maybe time to hang up my keyboard. :)

Cursor Grabbing while using drag_and_drop_by_offset (Python/Selenium)

I need to drag this scale and when I run this code:
HandScale = browser.find_element_by_xpath('//*[#data-xform="scale"]')
GridLineX = browser.find_element_by_class_name('outlined')
bottomLeft = browser.find_element_by_class_name('bottomLeft')
print GridLineX.size
action_chains = ActionChains(browser)
action_chains.drag_and_drop_by_offset(HandScale, 30, 30).click_and_hold(HandScale).perform()
It still has the grabbing effect Shown here:
Is there anyway to remove this effect before running the other part of my script?
I think you just need the release() function in action_chains which is designed to do exactly that. The line to add at the end of your current file would be:
action_chains.release().perform()
Edit after feedback that this didn't work: what if you do the release() inside your existing action_chains, and simply add a pause() after your click_and_hold(HandScale) so that the click is actually held and not immediately released. Finally, since you use a webelement argument in click_and_hold(HandScale) I would try to release on that element with release(HandScale). So, your action_chains might do what you want if you use the following:
action_chains.drag_and_drop_by_offset(HandScale, 30, 30).click_and_hold(HandScale).pause(5).release(HandScale).perform()
If THAT doesn't work, the WebDriver API has a method called reset_actions() that, according to the documentation "Clears actions that are already stored locally and on the remote end". I would add this under your current action_chains, but you could try inserting it before perform() in your current code. The line to add would just look like this:
action_chains.reset_actions().perform()
If none of this works for you, you could try
driver.execute_script("arguments[0].removeAttribute('cursor')", element")
If you need I think can help you figure out what to execute if none of the above works.

Why PyAutoGui LocateOnScreen() only Returns None

Here's the code that I'm trying to run:
import pyautogui
r=pyautogui.locateOnScreen('C:\Users\David\Desktop\index.png',grayscale=False)
print r
It has to be a pixel-perfect match in order to be found. To allow for any sort of deviance you can invoke a confidence parameter.
For example:
loc = pyautogui.locateOnScreen(image, grayscale=True, confidence=.5)
However, in order to use the confidence parameter you have to have opencv_python installed. This is easy to install with pip:
./python -m pip install opencv_python
After that is in place, you should be able to account for minor differences.
I was encountering the same problem, what I did is
import pyautogui
r= None
while r is None:
r=pyautogui.locateOnScreen('C:\Users\David\Desktop\index.png',grayscale=False)
print r
I think its just because that it takes time to locate image. If you found a better solution share with me :)
I had the similar problem.
My fault was I had saved the compare picture as jpg first and then as png in MS paint.
Be sure to save the compare picture as png format. After this the Locate function worked for me.
I had same issue and kept returning None value.
I did several trials and found the solution for me.
OS : MacOS
I saved photo with my system screenshot tool ( command+shift+5) and saved. it seems it's different pixel info as what it's displayed in my screen.
Therefore I used pyautogui screenshot instead to save the photo which I wanted to.
pyautogui.screenshot('num7_.png', region=(260,360, 110, 100))
After that, it's working good regardless of grayscale parameter.
pyautogui.locateOnScreen('num7_.png')
Box(left=260, top=360, width=110, height=100)
The locateOnScreen() function returns None if the image wasn't found on the screen. Remember, the match has to be pixel-perfect in order to match it, so be sure to crop index.png to the smallest recognizable size to prevent extra details from ruining your match. Also, make sure the thing you are looking for is not obscured by any other windows on top of it.
I got this working by using the following:
r = None
while r is None:
r = pyautogui.locateOnScreen('rbin.PNG', grayscale = True)
print icon_to_click + ' now loaded'
The key is to make grayscale = True.
The official documentation says;
The Locate Functions
NOTE: As of version 0.9.41, if the locate functions can’t find the provided image,
they’ll raise ImageNotFoundException instead of returning None.
So you can decide whether an exception was raise or not. Also you should try for a finite number of times not a While True loop.
retry_counter = 0
while retry_counter < 5:
try:
result = pyautogui.locateOnScreen(IMAGE_PATH_TO_FIND)
if result:
time.sleep(1)
retry_counter = 10 # to break the loop
except:
time.sleep(1) # retry after some time, i.e. 1 sec
retry_counter += 1
I found that if you program a pause of 1 or 2 seconds (using time.sleep), then it is able to locate the image. It also takes time for python to locate the image (my computer took about 5 seconds).
I had that problem but then i crop the photo into specific part then it was locating and yes it takes time.
or this can also work.
b = pyautogui.center('calc7key.png')
I found a way to fix my problem. Only search for an image as small as possible. A picture that is only 1 pixel is found after 3 seconds. And when i try to search for an image over 500x500 then it won't find anything.
I think that the library pyautogui needs several recognition points. For example, Number seven on calculator:
The number seven on the calculator of windows 10. In this format, I´ve got the location on the screen.
Thank you for your comments
My problem was I was trying to take a snip of the calculator button. That must make a different pixel match because I tried every other option in here and nothing was working. I did a print screen then cropped it to the button I wanted and it worked.
Before
import pyautogui
image = '9.png'
loc = pyautogui.locateOnScreen(image, grayscale=True, confidence=.5)
print (loc)
Error:
None
>>>
Solution
import pyautogui
import time
time.sleep(5)
image = '9.png'
loc = pyautogui.locateOnScreen(image, grayscale=True, confidence=.5)
print (loc)
Summary: Just add this two lines:
import time
time.sleep(5)
Output
Box(left=1686, top=248, width=70, height=47)
>>>
import time
time.sleep(5)
If you have taken screenshot with snipping tool it wont work, so take screenshot with "prt sc" or command prompt. This worked for me!
I am sure most of you guys know this, but if you forget to run your python script or IDE (wether that be Visual Studio, Python IDLE, etc.) as an administrator, then pyautogui will not be able to use the click command. It will still be able to move the mouse around, but it just won’t be able to click (this is true for all operating systems, they prevent any software that dose not have administrative privileges from clicking and i think it also prevents the software from using the keyboard but I am not sure. The OS dose this as a security measure so no software can do malicious things on your computer without your consent, like for instance: prompting the user to allow the software administrator access, and then taking control of the mouse and keyboard to click the “Yes” button for the user). If you’re using Linux or Mac then I am sure you know: you would have to use the “sudo” command. Hope this helps someone ;)

turn displays on with python under Windows 7 64bit

I'm trying to turn displays on using python. Found this code very useful but the problem is that it is turning display on for a brief moment and after like 1 second all displays are still 'entering power-save mode'. How can I make this 'power on' feature permanently?
Thanks for the hint, martineau! Simple sending message like that will not work:
win32gui.SendMessage(win32con.HWND_BROADCAST, win32con.WM_SYSCOMMAND, SC_MONITORPOWER, -1)
I also tried:
ctypes.windll.user32.SetCursorPos(100, 20)
and
pygame.mouse.set_pos((random.choice(range(600)), random.choice(range(600))))
to utilise mouse, but this is nothing when compare to:
win32api.mouse_event(win32con.MOUSEEVENTF_ABSOLUTE|win32con.MOUSEEVENTF_MOVE,100,20)
mouse_event did the trick as explained here

splinter - strange ElementNotVisible exception for link that is indeed visible in dumped html/screenshot

I am running some browser tests with splinter and, at one point, come across a page with a link I want to follow. This call succeeds and returns the link:
my_browser.find_link_by_partial_href('/mystuff/' + str(important_number))
But I cannot click it:
my_browser.find_link_by_partial_href('/mystuff/' + str(important_number)).click()
...
...
...
ElementNotVisibleException: Message: u'{"errorMessage":"Element is not currently visible and may not be manipulated","request":{"headers":{"Accept":"application/json","Accept-Encoding":"identity","Connection":"close","Content-Length":"81","Content-Type":"application/json;charset=UTF-8","Host":"127.0.0.1:38495","User-Agent":"Python-urllib/2.7"},"httpVersion":"1.1","method":"POST","post":"{\\"sessionId\\": \\"7812e810-9100-11e4-881c-37067349397d\\", \\"id\\": \\":wdc:1420039695427\\"}","url":"/click","urlParsed":{"anchor":"","query":"","file":"click","directory":"/","path":"/click","relative":"/click","port":"","host":"","password":"","user":"","userInfo":"","authority":"","protocol":"","source":"/click","queryKey":{},"chunks":["click"]},"urlOriginal":"/session/7812e810-9100-11e4-881c-37067349397d/element/%3Awdc%3A1420039695427/click"}}' ; Screenshot: available via screen
What's odd here is that the link is indeed present when I follow my_browser.url, as well as if I look at my_browser.html or trybrowser.show_screenshot(my_browser).
And it doesn't seem to be an issue of waiting for visibility. Adding a quick import time(); time.wait(5); before the click still doesn't work (nor do longer waits, though that's probably more than sufficient).
What could I be missing here?
Ah. Splinter is defaulting to the first link it finds, which isn't visible:
(Pdb) [link.visible for link in my_browser.find_link_by_partial_href('/mystuff/' + str(important_number))]
[False, True]
This extra hidden link isn't supposed to be there in the first place, which goes to show you what can happen if you make assumptions about your code - even the seemingly irrelevant parts!

Categories