I am on a side project to write python script to auto-login a website.
I am trying to use python script to launch FireFox browser and auto-login into a website
Below is the source code of the element i'm trying to locate:
source code
I used below
item_email= WebDriverWait(driver,10).until(EC.presence_of_element_located((By.XPATH, "//input[contains(#id,'username')]")))
or below
item_email= WebDriverWait(driver,10).until(EC.presence_of_element_located((By.XPATH, "//input[contains(#id,'username')]")))
or below
item_email = WebDriverWait(driver,10).until(EC.presence_of_element_located((By.XPATH, "//input[#id='j_id0:j_id5:loginComponent:loginForm:username']")))
They all ended up with selenium.common.exceptions.TimeoutException
I was able to locate elements when the input ID didn't have colons (not with namespace, i guess)
erhai950,
Explicit wait will always end up in selenium.common.exceptions.TimeoutException exception if the element is not found in HTMLDOM for any reason.
You can try the below xpath:
//input[contains(#id,'username') and #placeholder='Email']
Press F12 in Chrome -> go to element section -> do a CTRL + F -> then paste and see //input[contains(#id,'username') and #placeholder='Email'] if your desired element is getting highlighted or not.
Now if we have 1/1 matching entry then try below code:
item_email = driver.find_element(By.XPATH, "//input[contains(#id,'username') and #placeholder='Email']")
or
item_email= WebDriverWait(driver,10).until(EC.presence_of_element_located((By.XPATH, "//input[contains(#id,'username') and #placeholder='Email']")))
Also check if this web element is in iframe or not.
Given the HTML:
the element is a <input> element which would accept text input.
Solution
Ideally to send a character sequence to an <input> element you need to induce WebDriverWait for the element_to_be_clickable() and you can use either of the following locator strategies:
Using CSS_SELECTOR:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "div.form-group input[id$='username'][name$='username'][placeholder='Email']"))).send_keys("erhai950")
Using XPATH:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//div[#class='form-group']//input[contains(#id, 'username') and contains(#name, 'username')][#placeholder='Email']"))).send_keys("erhai950")
Note: You have to add the following imports :
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
Related
I am testing a webapp created with python dash using selenium. I am trying to click a tab but always get the ElementClickIntercepted Exception.
Note: Of course I stumbled over similiar problems but most times the problem is that the element cannot be clicked as is did not load yet - I already built in waits! - or the fact that another element would receive the click which cannot be the case either. Note that the first item is always preselected and i want to choose the second.
#Selct X-Axis
x_axis = driver.find_element(By.XPATH, "//*[#id='navbar']/a[2]")
x_axis.click()
driver.implicitly_wait(2)
try:
WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.XPATH, "//a[text()='Even']"))
)
except:
raise Exception
even= driver.find_element(By.XPATH, "//a[text()='Even']")
even.click()
Exception snapshot:
HTML snapshot:
Based on what you've posted, By.XPATH, "//a[text()='Even']" is probably selecting an HTML element different from what you're expecting.
There appears to be an <a> with text that starts with 'Even', but you've shown nothing with text that equals 'Even'.
BTW, when asking a question, you ought to at least paste the relevant HTML as text, rather than as a screenshot.
Use contains(text(), 'even') instead of text()='even' in your XPath. Because, text()='even' means the text must be 'even' but not contain 'even', and in your HTML code, the text seems not only have 'even'.
To click on either of the element instead of presence_of_element_located() you need to induce WebDriverWait for the element_to_be_clickable() and you can use either of the following locator strategies:
$$$ Response:
Using PARTIAL_LINK_TEXT:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.PARTIAL_LINK_TEXT, "Response"))).click()
Using XPATH:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//div[starts-with(#id, 'content')]//ul//div[#class='nav-item']//a[contains(., 'Response')]"))).click()
Even $$$:
Using PARTIAL_LINK_TEXT:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.PARTIAL_LINK_TEXT, "Even"))).click()
Using XPATH:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//div[starts-with(#id, 'content')]//ul//div[#class='nav-item']//a[starts-with(., 'Even')]"))).click()
Note: You have to add the following imports :
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
I have been trying to make a Selenium bot that searches for a word on github, clicks on the first link and then downloads it with Python 3.8 and I got stuck with making the bot click on the hyperlink. I understand that I can make the bot click on it with driver.find_element(By.XPATH, "Xpath").click() but I want to be able to find the path of the href with another method for the sake of learning, in this case CSS_SELECTOR. Source code of the first hyperlink result is like this:
HTML:
Since every single result is under the same "a" selector with a class of "v-align-middle", I thought of using this code: driver.find_element(By.CSS_SELECTOR, ".v-align-middle").click() but it did not seem to work. What am I missing?
The desired element is a dynamic element, so to click() on the element you need to induce WebDriverWait for the element_to_be_clickable() and you can use either of the following locator strategies:
Using CSS_SELECTOR:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "a.v-align-middle[href='/asdf-vm/asdf'][data-hydro-click][data-hydro-click-hmac]"))).click()
Using XPATH:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//a[#class='v-align-middle' and #href='/asdf-vm/asdf'][#data-hydro-click and #data-hydro-click-hmac]"))).click()
Note: You have to add the following imports :
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
I have ion-input tags in my app and that creates another input tag as a sibling. The sibling input is responsible for any input value.
I want to access that sibling to enter a value using selenium Python (can be using send_keys or using javascript_executor
<ion-input data-cy="email" type="email" debounce="50" value="" class="sc-ion-input-md-h sc-ion-input-md-s md">
<input class="native-input sc-ion-input-md" autocapitalize="off" autocomplete="off"
autocorrect="off" name="ion-input-0" placeholder="" spellcheck="false" type="email"></ion-input>
Everytime I use that data-cy="email" I am getting elementNotFound exception only.
I am using Selenium python.
The element should be unique in nature, based on the HTML that you've shared, can you check this CSS or XPATH
XPATH:
//input[#class='native-input sc-ion-input-md' and #type='email' and#name='ion-input-0']
CSS_SELECTOR:
input[class='native-input sc-ion-input-md'][type='email'][name='ion-input-0']
Please check in the dev tools (Google chrome) if we have unique entry in HTML DOM or not.
Steps to check:
Press F12 in Chrome -> go to element section -> do a CTRL + F -> then paste the xpath/css and see, if your desired element is getting highlighted with 1/1 matching node.
If they happen to be unique in nature you can try with the below code:
Code1:
wait = WebDriverWait(driver, 30)
input = wait.until(EC.visibility_of_element_located((By.XPATH, "//input[#class='native-input sc-ion-input-md' and #type='email' and#name='ion-input-0']")))
input.send_keys('the string that you want to send')
Code2:
wait = WebDriverWait(driver, 30)
input = wait.until(EC.visibility_of_element_located((By.XPATH, "//input[#class='native-input sc-ion-input-md' and #type='email' and#name='ion-input-0']")))
driver.execute_script("arguments[0].setAttribute('value', 'the string that you want to send')", input)
Imports:
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
I don't any such major issues in your code attempts. However the the desired element is a dynamic element, so ideally to send a character sequence to the element you need to induce WebDriverWait for the element_to_be_clickable() and you can use either of the following Locator Strategies:
Using CSS_SELECTOR:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "ion-input[data-cy='email'] > input[type='email'][name^='ion-input']"))).send_keys("Sarath#N.com")
Using XPATH:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//ion-input[#data-cy='email']/input[#type='email' and starts-with(#name, 'ion-input')]"))).send_keys("Sarath#N.com")
Note: You have to add the following imports :
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
It was so easy. I have been using either XPATH or CSS_SELECTOR hence always it does not penetrate to the input tag that was created by ion. Instead of the bespoke one, i have used TAGNAME and that did the magic
email = [(By.XPATH, "ion-input[data-cy='email'] input")]
Instead use like this
email = [(By.TAGNAME, "ion-input[data-cy='email']")]
I would like to get all attribute values names 'href' from a website, there are like 10 of them. I have successfully got one using the following method:
url = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "/html/body/div[2]/div[2]/div/div/div[2]/section[1]/div/div[2]/div[3]/ul/li[1]/div/div[1]/span/a"))).get_attribute("href")
The problem with this is it's only giving back one not all of them. I have tried to go by ID but it doesn't return anything:
url = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.ID, "a"))).get_attribute("href")
Also, the other href values are located in different xpaths:
/html/body/div[2]/div[2]/div/div/div[2]/section[1]/div/div[2]/div[3]/ul/li[2]/div/div[1]/span/a
/html/body/div[2]/div[2]/div/div/div[2]/section[1]/div/div[2]/div[3]/ul/li[3]/div/div[1]/span/a
/html/body/div[2]/div[2]/div/div/div[2]/section[1]/div/div[2]/div[3]/ul/li[4]/div/div[1]/span/a
Here's my element:
<a ph-tevent="job_click" ref="linkEle" href.bind="getUrl(linkEle, 'job', eachJob, '', eachJob.jobUrl)" data-ph-at-id="job-link" data-ph-id="ph-page-element-page20-CRUCUZ" class="au-target" au-target-id="181" ph-click-ctx="job" ph-tref="12313123213" ph-tag="ph-search-results-v2" href="https://hyperlink.com" data-ph-at-job-title-text="title" data-ph-at-job-location-text="Unknown" data-ph-at-job-location-area-text="asd" data-ph-at-job-category-text="Manufacturing" data-access-list-item="2" data-ph-at-job-id-text="A123124" data-ph-at-job-type-text="Regular" data-ph-at-job-industry-text="Manufacturing" data-ph-at-job-post-date-text="2021-12-09T00:00:00.000Z" data-ph-at-job-seqno-text="ASD212ASFS" aria-label="Senior Manager">
<div class="job-title" data-ph-id="ph-page-element-page20-0Mi3Ce">
<!--anchor-->
<!--anchor-->
<span data-ph-id="ph-page-element-page20-PLxqta">Senior Manager </span>
</div><!--anchor--> </a>
Any help is appreciated!
For finding more than one web element, you should either use find_elements or if you are using Explicit waits then you can use presence_of_all_elements_located or visibility_of_all_elements_located.
Based on the HTML that you've shared, if
this css
a[ph-tevent='job_click'][ref='linkEle']
or this xpath
//a[#ph-tevent='job_click' and #ref='linkEle']
represent all the nodes, to check below are the steps:
Please check in the dev tools (Google chrome) if we have all desired nodes entry in HTML DOM or not.
Steps to check:
Press F12 in Chrome -> go to element section -> do a CTRL + F -> then paste the xpath and see, if your desired elements are getting highlighted or not.
If they are then the below code should work:
for ele in driver.find_elements(By.XPATH, "//a[#ph-tevent='job_click' and #ref='linkEle']"):
print(ele.get_attribute('href'))
To extract the value of the href attributes using Selenium and python you have to induce WebDriverWait for visibility_of_all_elements_located() and you can use either of the following Locator Strategies:
Using CSS_SELECTOR:
print([my_elem.get_attribute("href") for my_elem in WebDriverWait(driver, 20).until(EC.visibility_of_all_elements_located((By.CSS_SELECTOR, "a[ph-tevent='job_click'][ref='linkEle'][data-ph-at-id='job-link'][ph-click-ctx='job'][href]")))])
Using XPATH:
print([my_elem.get_attribute("href") for my_elem in WebDriverWait(driver, 20).until(EC.visibility_of_all_elements_located((By.XPATH, "//a[#ph-tevent='job_click' and #ref='linkEle'][#data-ph-at-id='job-link' and #ph-click-ctx='job'][#href]")))])
Note : You have to add the following imports :
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
I am trying to create an automated download event for one ERP platform using Selenium in python. This is a bit tricky for this part as there is no specific element to find and click.
Multiple buttons have the same class and no id for the highlighted button (DATABASE/BACKUP)
Can anyone help me with the same?
event flow >>
Login page > click "administration button" > click "database / backup"
thanks
As per Selenium documentation https://selenium-python.readthedocs.io/locating-elements.html you can find all of the elements by their class name and then access them by index ([index_number]).
all_buttons = driver.find_elements_by_class_name("your_class_name")
then you can do something like:
button_to_click = all_buttons[3] # The 4th button which has index 3 in all the retrieved buttons by class name
driver.find_element(By.XPATH,"//a[contains(text(),'Database / Backup')]").click()
Simply click the a tag which contains the text.
To click on the element with text as DATABASE/BACKUP you can use either of the following Locator Strategies:
Using xpath:
driver.find_element(By.XPATH, "//a[#class='menui' and contains(., 'DATABASE/BACKUP')]").click()
Using xpath:
driver.find_element(By.XPATH, "//a[text()[contains(., 'DATABASE/BACKUP')]]").click()
The desired element is a dynamic element, ideally to click on a clickable element you need to induce WebDriverWait for the element_to_be_clickable() and you can use either of the following Locator Strategies:
Using XPATH:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//a[#class='menui' and contains(., 'DATABASE/BACKUP')]"))).click()
Using XPATH:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//a[text()[contains(., 'DATABASE/BACKUP')]]"))).click()
Note: You have to add the following imports :
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC