Selenium: [Python] ActionChains click().perform() clicking previous elements

Created on 26 May 2020  路  6Comments  路  Source: SeleniumHQ/selenium

馃悰 Bug Report

As I asked here on StackOverflow - https://stackoverflow.com/questions/62029676/selenium-action-clicking-on-every-element-before-current
Basically, if you get a list of elements and run through them in a loop, action click().perform() will click on every previous element before clicking the current one. Tested on Chromium and Firefox, same result.

How it should behave

action.move_to_element(element).click().perform() should only click the current item of the looped list.

Steps to reproduce

The following code is the one I'm using

import time
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.action_chains import ActionChains

browser = webdriver.Chrome()
browser.get("https://getbootstrap.com/docs/4.0/examples/checkout/")
action = ActionChains(browser)

inputs = browser.find_elements_by_tag_name("input")

for currentInput in inputs:
    if currentInput.get_attribute("type") == "text":
        action.move_to_element(currentInput).move_by_offset(5,5).click().perform()
        currentInput.send_keys("this is text thing")
    time.sleep(0.2)

assert "No results found." not in browser.page_source
time.sleep(2)
browser.close()

Save it with any .py name and execute it with python. For firefox, add browser.execute_script("arguments[0].scrollIntoView(true);", currentInput); before the if, or it'll throw "out of bounds exception" on the first try.
Changing the if to catch only "radio" type inputs will have the same problem, it'll select the first option, then 1-2, then 1-2-3.

Environment

OS: Ubuntu 20.04
Browser: Chromium and Firefox
Browser version: 83 (Chromium) and 76 (Firefox)
Browser Driver version:
Language Bindings version: Python 3.7.0
Selenium Grid version (if applicable):

needs-triaging

All 6 comments

To be sure, this is not a problem with that specific page. I have tried with these other pages and the issue happened on them as well:
https://sites.uwm.edu/mdisc/forum-signup/
https://www.createaforum.com/free-forum.php

EDIT: putting action.reset_actions() right before the line with the click.perform doesn't do anything either, just in case.

EDIT2: Testing in another case, without going into any loops. I simply got 3 different elements from a page into 3 different variables. Each call of action.move_to_element(element).click().perform()also moved to and clicked on the previous item, even if there was an action.reset_actions()right above. So it's not a problem within the loop, but it looks like ActionChains is not properly cleaning its list of actions to do, at least in Python.
With one more test, I've found that calling perform() only once, at the end of the script, will make it behave as intended. That makes me wonder if the problem is within the perfom() function, as it is not clearing its action list.

Can you test with the latest alpha using pip install --pre selenium?

It seems to be working as intended now. Tested a few cases and there's no more repeating of previous actions. Thank you!

Closing after last comment

I've had the same problem, basically action_chains.move_to_element_with_offset would keep running against the first element in a loop of elements. The problem was fixed when I upgraded from 3.141.0 to 4.0.0a6.post2. Thank you @Dude-X !

i've had a same problem with selenium(3.141.0)
using a for loop with move_to_element to iterate through few different elements from a page
every self.action.move_to_element(element).perform() starts from element[0] instead of current element of the looped list

pip install selenium==4.0.0a6.post2 works fine, Thanks to @himelpdas and @Dude-X

Was this page helpful?
0 / 5 - 0 ratings