-1

again. This is the second time I am asking this question and I really want to figure out what happens.

Summary: I want to click a "agree and continue" button on paypal with selenium. The button changes from "continue" to "agree and continue". I tried various ways of clicking it and sometimes it works, sometimes it doesn't. It prints "clicked" as it's already clicked, but it won't proceed to the next page.

"continue" button (before the change)

<button class="ppvx_btn___5-8-2" aria-live="assertive" id="payment-submit-btn" data-testid="submit-button-initial" data-disabled="true" xpath="1">Continue<span class="ppvx_btn--state__screenreader___5-8-2"></span></button>

"agree and continue" button (after the change)

<button class="ppvx_btn___5-8-2" aria-live="assertive" id="payment-submit-btn" data-testid="submit-button-initial" data-disabled="false" xpath="1">Agree &amp; Continue<span class="ppvx_btn--state__screenreader___5-8-2"></span></button>

What I've tried:

mainagree = WebDriverWait(driver, 20).until(
EC.presence_of_element_located((By.XPATH, "//button[@id='payment-submit-btn'][@data- 
disabled='false']")).click()
print('clicked')

I also tried to_be_clickable

mainagree = WebDriverWait(driver, 20).until(
EC.element_to_be_clickable((By.XPATH, "//button[@id='payment-submit-btn'][@data- 
disabled='false']")).click()  

It works like half of the time which confuses me a lot, and sometimes I got this error when it didn't work

selenium.common.exceptions.ElementClickInterceptedException: Message: element click intercepted: Element is not clickable at point (951, 965)

(Session info: chrome=91.0.4472.27)

Shi O
  • 51
  • 8
  • I might suspect the element becomes only briefly clickable. Maybe consider putting in a couple 'clickable' checks with a small delay between. – sytech May 02 '21 at 19:04

2 Answers2

0

First of all try locating the element by this xpath:
//button[@data-testid='submit-button-initial']
This locator should not change by clicking the element.
Second: Try using visibility_of_element_located expected condition instead of element_to_be_clickable and if this still not helped add time.sleep(1) delay after the expected condition of visibility_of_element_located or element_to_be_clickable
If you don't want to add a hardcoded delay try scrolling the element in to the view by something like this

from selenium.webdriver.common.action_chains import ActionChains

element = driver.find_element_by_id("the_element_id")

actions = ActionChains(driver)
actions.move_to_element(element).perform()

and only after that click on it.
As you can see here sometimes there is no way to overcome this problem without a short hardcoded delay. It can be a short delay, something about 200-300 mill seconds, but this is the only solution if other approaches do not help.
The hardcoded delay should be used in addition and after the expected condition was fulfilled.

Prophet
  • 32,350
  • 22
  • 54
  • 79
  • I also tried with visibility_of_element and it still gives me same error. I believe if I add time.sleep, it will eliminate the issue but I want this script to react as soon as the visibility of that element appears. – Shi O May 02 '21 at 18:42
  • I edited the answer. Please let me know if now it works better – Prophet May 02 '21 at 18:48
  • Hi again, I also tried this method, and it still clicked like half of the time. I believe you reply to my previous [post] before. [post]: https://stackoverflow.com/questions/67321445/how-do-i-select-a-changed-button-in-this-case-on-selenium – Shi O May 02 '21 at 18:56
  • Yup. I updated the answer once more. Sometimes there is no other way, only the hardcoded delay. Not instead, but after and in addition to the expected condition was satisfied. – Prophet May 02 '21 at 19:01
  • yah, i tried this without the hardcoded display, and the issue was still there. I also checked the article that you linked when I posted my previous post. Thinking there maybe an alternate solution. Thank you for your help nonetheless – Shi O May 02 '21 at 19:31
0

The solution seems relatively easy to me. Just wait for exact text:

button = WebDriverWait(driver, 20).until(
EC.element_to_be_clickable((By.XPATH, 
"//button[contains(text(), 'Agree &amp; Continue')]"
button.click()

Or,

//button[contains(text(), 'Agree & Continue')]
vitaliis
  • 4,082
  • 5
  • 18
  • 40