Issue
I can't write inside an input that is inside a modal. This modal is open after clicking a button.
The following is the link :
https://www.portalinmobiliario.com/MLC-2148268902-departamento-los-espinos-id-116373-_JM#position=1&search_layout=grid&type=item&tracking_id=eba8327b-85c0-4317-8c63-7c69c5b34e16
First, with this function the button is click:
def button_click(self, xpath):
time.sleep(2)
button = self.driver.find_element(
By.XPATH, xpath)
button.click()
time.sleep(5)
The xpath of the button is the following:
"/html/body/div[2]/div/button"
Once the modal is open I try manipulating the input of the modal and write inside. I use the following function:
def write_input(self, xpath, answer):
time.sleep(2)
winput = self.driver.find_element(
By.XPATH, xpath)
winput.send_keys(answer)
time.sleep(5)
Try with this xpath:
/html/body/div[4]/div/div/div[2]/div[2]/div/div[2]/form/div[1]/div[1]/div/input
Get the following error:
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":"/html/body/div[4]/div/div/div[2]/div[2]/div/div[2]/form/div[1]/div[1]/div/input"}
The flow is Open link --> Click Button "Contactar" --> Modal is open with inputs
How can I find the elements inside the modal?
Solution
Your button has debounce logic, assigned to it. That means that click action would be succeed only after debounce was ended. That can be 1+ seconds (it depends on site implementation).
So clicking on the button after rendering wouldn't trigger modal. You need to wait for some time via dirty time.sleep(2)
or more or implement retry logic click_with_retry
.
And try to avoid absolute xPath. Your resource has unique and readable attributes that can be used to build unique locators.
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
def click_and_wait_for_modal_with_retry(driver, max_retries, button_locator, by, dialog_locator):
retries = 0
while retries < max_retries:
button = WebDriverWait(driver, 10).until(EC.presence_of_element_located(button_locator))
button.click()
time.sleep(0.5)
if len(driver.find_elements(by, dialog_locator)) > 0 and driver.find_elements(by, dialog_locator)[0].is_displayed():
return
retries += 1
raise Exception('Retries exceeded')
driver = webdriver.Chrome()
wait = WebDriverWait(driver, 20)
driver.maximize_window()
driver.get(
'https://www.portalinmobiliario.com/MLC-2148268902-departamento-los-espinos-id-116373-_JM#position=1&search_layout=grid&type=item&tracking_id=eba8327b-85c0-4317-8c63-7c69c5b34e16')
consent = wait.until(EC.presence_of_element_located((By.ID, 'newCookieDisclaimerButton')))
consent.click()
wait.until(EC.staleness_of(consent))
click_and_wait_for_modal_with_retry(driver, 3, (By.CSS_SELECTOR, 'button[type=primary] .andes-button__content'),
By.CSS_SELECTOR, '.andes-modal__overlay')
dialog = wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, '.andes-modal__overlay')))
wait = WebDriverWait(dialog, 10)
name = wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, '[data-testid=name-input]')))
name.send_keys('name')
Answered By - Yaroslavm
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.