How do I get Selenium Button Click to work?

Question:

I’m a complete beginner, I have a website in which I want to click a button through python selenium, I’ve tried a lot of things, but I can’t get it to work.

import time
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC


chromedriver_location = executable_path=r"C:UsersHPDesktopchromedriver_win32chromedriver.exe"

driver = webdriver.Chrome(chromedriver_location)
driver.get('https://maskun.org/donate/')

donate_button = WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//button[contains(@class, 'give-btn advance-btn')] and text()='Donate Now']")))
donate_button.click()

Right now, I’m getting the error:

Traceback (most recent call last):
  File "d:pythonprojectsmaskun.py", line 13, in <module>
    donate_button = WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//button[contains(@class, 'give-btn advance-btn')] and text()='Donate Now']")))
  File "C:PythonPython310libsite-packagesseleniumwebdriversupportwait.py", line 81, in until
    value = method(self._driver)
  File "C:PythonPython310libsite-packagesseleniumwebdriversupportexpected_conditions.py", line 312, in _predicate
    target = driver.find_element(*target)  # grab element at locator
  File "C:PythonPython310libsite-packagesseleniumwebdriverremotewebdriver.py", line 856, in find_element
    return self.execute(Command.FIND_ELEMENT, {
  File "C:PythonPython310libsite-packagesseleniumwebdriverremotewebdriver.py", line 429, in execute
    self.error_handler.check_response(response)
  File "C:PythonPython310libsite-packagesseleniumwebdriverremoteerrorhandler.py", line 243, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.InvalidSelectorException: Message: invalid selector: Unable to locate an element with the xpath expression //button[contains(@class, 'give-btn advance-btn')] and text()='Donate Now'] because of the following error:
SyntaxError: Failed to execute 'evaluate' on 'Document': The string '//button[contains(@class, 'give-btn advance-btn')] and text()='Donate Now']' is not a valid XPath expression.      
  (Session info: chrome=106.0.5249.119)
Stacktrace:
Backtrace:
        Ordinal0 [0x00B51ED3+2236115]
        Ordinal0 [0x00AE92F1+1807089]
        Ordinal0 [0x009F66FD+812797]
        Ordinal0 [0x009F92B4+823988]
        Ordinal0 [0x009F9165+823653]
        Ordinal0 [0x009F9400+824320]
        Ordinal0 [0x00A25352+1004370]
        Ordinal0 [0x00A257CB+1005515]
        Ordinal0 [0x00A57632+1209906]
        Ordinal0 [0x00A41AD4+1120980]
        Ordinal0 [0x00A559E2+1202658]
        Ordinal0 [0x00A418A6+1120422]
        Ordinal0 [0x00A1A73D+960317]
        Ordinal0 [0x00A1B71F+964383]
        GetHandleVerifier [0x00DFE7E2+2743074]
        GetHandleVerifier [0x00DF08D4+2685972]
        GetHandleVerifier [0x00BE2BAA+532202]
        GetHandleVerifier [0x00BE1990+527568]
        Ordinal0 [0x00AF080C+1837068]
        Ordinal0 [0x00AF4CD8+1854680]
        Ordinal0 [0x00AF4DC5+1854917]
        Ordinal0 [0x00AFED64+1895780]
        BaseThreadInitThunk [0x76046739+25]
        RtlGetFullPathName_UEx [0x77858FD2+1218]
        RtlGetFullPathName_UEx [0x77858F9D+1165]

If I inspect the button on chrome I get:

<button class="give-btn advance-btn" tabindex="1">Donate Now<i class="fas fa-chevron-right"></i></button>

The XPath is:

//*[@id="give-form-746-1"]/div[1]/button
Asked By: Hafsah Nasir

||

Answers:

You have a syntax error inside the XPath expression.
Also, you need to scroll the page down and switch to the iframe block since that button is inside an iframe.
The following code works

import time

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
options = Options()
options.add_argument("start-maximized")

webdriver_service = Service('C:webdriverschromedriver.exe')
driver = webdriver.Chrome(service=webdriver_service, options=options)
url = 'https://maskun.org/donate/'
driver.get(url)
wait = WebDriverWait(driver, 20)
driver.execute_script("window.scrollBy(0, arguments[0]);", 600)
time.sleep(1)
wait.until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR, "iframe[name='give-embed-form']")))

wait.until(EC.presence_of_element_located((By.XPATH, "//button[contains(@class, 'give-btn advance-btn') and text()='Donate Now']"))).click()

Don’t forget to switch from the iframe when you finished working inside it with

driver.switch_to.default_content()
Answered By: Prophet

you need to switch to frame first than find_elemnt

driver.get('https://maskun.org/donate/')
iframe = driver.find_element(By.XPATH, "//iframe[@name='give-embed-form']")
driver.switch_to.frame(iframe)
donate_button = driver.find_element(By.XPATH, "//button[contains(text(), 'Donate Now')]")
Answered By: ammar alkotb