Python Selenium on AngularJs site - python

I am trying to automate reading my phone bill from the carrier website. www.fido.ca
However, the site is built with angularjs and I can't find the element using python and selenium webdriver. Please see below for the codes I've tried.
driver = webdriver.Firefox()
url = 'https://www.fido.ca/pages/#/login?m=login'
driver.get(url)
wait = WebDriverWait(driver, 10)
wait.until(EC.visibility_of_element_located((By.XPATH, "//a[#id='BC']")))
It returns selenium.common.exceptions.TimeoutException: Message:
Note: I can see the element from the front end, but no idea why webdriver can't see it.

When you navigate to a page, you would see the overlay "Welcome to Fido!" screen which makes your desired element invisible - hence the timeout error.
Handle the screen by selecting a region and clicking "Continue" or "X" (close).

Related

Selenium Python Can't click button: ElementNotInteractable or StaleElementReferenceException

I'm trying to automate MS Teams and can't get past the login because after entering the password I am having issues clicking the Sign In button.
If I try:
button = driver.find_element_by_xpath('//*[#id="idSIButton9"]')
button.click()
I get:
ElementNotInteractableException: Message: element not interactable.
If I try to solve it with Action Chains method (which seems to have solved many similiar issues for lots of people):
button = driver.find_element_by_xpath('//*[#id="idSIButton9"]')
driver.implicitly_wait(10)
ActionChains(driver).move_to_element(button).click(button).perform()
I get:
StaleElementReferenceException: Message: stale element reference: element is not attached to the page document
It is worth mentioning that when logging in manually I can get past this stage with pressing return after entering my password but I couldn't be successful with send keys methods neither.
If you still filled the form use submit() function - It is there to make your life easier.
Import webdriver:
from selenium import webdriver
Create webdriver object:
driver = webdriver.Firefox()
Get the website:
driver.get("https://www.YOUR_WEBSITE.de/")
Get element - In your case input for password
element = driver.find_element_by_xpath('//*[#id="i0118"]')
Send keys - Enter password
element.send_keys("YOUR_PASSWORD")
Submit contents
element.submit()
The element which you are trying to locate using the XPath driver.find_element_by_xpath('//*[#id="idSIButton9"]') might be the part of the previous screen and new screen, hence the driver might be referring to the element which is part of the previous screen, hence you are getting the StaleElementReferenceException.
The simplest way to resolve this is you can add, driver.refresh() just before the above xpath, this will load the page and DOM with the new elements.
Else, you can use a different locator strategy which will uniquely identify that element.

Edge webdriver cannot find element visible to Firefox driver on SharePoint site

I am trying to access a dialog box on SharePoint using the Edge driver, however, my code doesn't find it. Using the Firefox driver, it works without problems:
[The reason I have to use Edge is because I am in a corporate environment, and Firefox is not supported by our single sign-on, proxies etc.]
from selenium import webdriver
import time
driver = webdriver.Edge()
#driver = webdriver.Firefox()
base_url = r"..../project/carb2_0/filedirectory/_layouts/15/groups.aspx"
driver.get(base_url)
time.sleep(1)
group = "AT01"
button= driver.find_element_by_xpath(r"//a[contains(text(),'File Directory - "+group+"')]")
button.click()
time.sleep(0.2)
button = driver.find_element_by_link_text("New")
button.click()
time.sleep(0.2)
driver.switch_to.frame(1)
time.sleep(0.2)
#t = driver.page_source
elem = driver.find_element_by_xpath(
r"//div[#id='ctl00_PlaceHolderMain_peoplePicker_TopSpan']/input[2]"
)
The last line throws an exception when using Edge,
NoSuchElementException: no such element: Unable to locate element: {"method":"xpath","selector":"//div[#id='ctl00_PlaceHolderMain_peoplePicker_TopSpan']/input[2]"}
(Session info: MicrosoftEdge=85.0.564.41)
Firefox is perfectly fine. Digging deeper, reading the page source with driver.page_source yields two completely different results. For Edge it is
<html><head></head><body></body></html>
For Firefox I get a full page, including an iframe, which can be found by find_element_by_xpath.
Any help would be appreciated.
The solution to the above issue was 2-fold:
switch to the correct frame
find the exact xpath denoting the <input> field in the page
For the first part I used the following code:
for i, frame in enumerate(frames):
if re.search('ms-dlgFrame', frame.get_attribute('outerHTML')):
frame_id = i
break
driver.switch_to.frame(frame_id)
It turns out the the correct frame_id was 2, not 1. It is not clear to me why the firefox (gecko) driver would work anyways (and the selenium IDE would select 1).
The second part boiled down to searching through the source of the HTML page and find the exact input element. Interestingly enough, the selenium IDE had only located a <div> around that element, and the firefox webdriver was forgiving enough to type into the correct field. The edge driver would not do that and claim that element was not writable. Once I had found the correct <input> field, everything worked fine.

Cannot locate search bar with selenium in python

I have been trying to locate a sidebar bar in this website https://covid19.who.int/?gclid=EAIaIQobChMIkoua643_6gIVDNd3Ch3qgApPEAAYASAAEgIfIvD_BwE
The search bar I am trying to locate is the one on top, which says "Search by Country, Territory, or Area"
I tried with XPATH but I always get error in locating the element, or sometimes it says that my element is not interactable (I guess that means that I am locating a different element)
Could please show a way to find that element?
here is what I saw when I inspected
Assuming that you want to search Country and see the data, So for that you need to locate the id of search box(i.e react-select-2-input) and enter the Country name using send_keys and hit enter.
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
site = 'https://covid19.who.int/?gclid=EAIaIQobChMIkoua643_6gIVDNd3Ch3qgApPEAAYASAAEgIfIvD_BwE'
driver = webdriver.Chrome(executable_path = 'chromedriver.exe') # Here I am using Chrome's web driver
#For Firefox Web driver
#driver = webdriver.Firefox(executable_path = 'geckodriver.exe')
driver.get(site)
time.sleep(3)
elem = driver.find_element_by_id("react-select-2-input")
elem.send_keys("Brazil")
elem.send_keys(Keys.ENTER)
If you are only interested in locating search-bar then you can locate it by it's id(driver.find_element_by_id("react-select-2-input"))
How did I find search-bar id?
Basically search-bar is nothing but a text-box and in HTML text-box code starts with <input type="text">, So I had to just find the HTML code of text box in inspect element of browser.
By seeing your screen-shot I can say you were going in right direction, just you had to expand div tag more till you find code of text box.

Unable to locate element in Python Selenium webdriver find_element_by_xpath

i'm trying to click the "download Results" button on this website .
i'm using below python code to click this button
from selenium import webdriver
chromedriver_path = 'E:/software/python/chromedriver'
url = 'https://www.cms.gov/apps/physician-fee-schedule/search/search-results.aspx?Y=0&T=4&HT=2&CT=3&H1=74750&H2=74800&M=5'
driver= webdriver.Chrome(executable_path=chromedriver_path )
driver.get(url)
driver.find_element_by_xpath('//*[#title="Download Results"]').click()
i'm getting below error
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":"//frame[#name="aspnetForm"]"}
(Session info: headless chrome=83.0.4103.116)
i'm thinking if the button is within a iframe but how do I find out the iframe?
This may help you out: Unable to locate element using selenium webdriver in python
Try and switch to the frame first, and then search for the element.
i realized that there's a agreement page that i need to click 'Agree' button first.
i didn't see this in browser because i already clicked 'Agree' weeks ago. but in webdriver, i need to click that each time.
Just after the URL opens, a page comes up asking you to agree the terms. You need to click on that Agree first. Since it is possible that once clicking on the Agree button, it won't come again if you accepted it on default browser. So just be sure with code, you can first check the presence of the agree button first.
This kind of function you may make to check presence:
def elementPresent(locatorType, locator):
#present = true
#not present = false
wait = WebDriverWait(driver, 20)
try:
wait.until(EC.presence_of_element_located((locatorType, locator)))
except Exception:
return False
return True
And then using if condition you may proceed further like:
if(elementPresent("xpath", "//a[#title='Accept']/span")):
driver.find_element_by_xpath("//a[#title='Accept']/span").click()
and then you may click on the element you want, there is no frame that is required to be switched to.
driver.find_element_by_xpath("//a[#title = 'Download Results']/span").click()
Just extract the element and click on it and your required file will be downloaded.

Can't locate element by xpath in selenium?

I am learning python and selenium right now by making a small script that posts birthday comments to my facebook friends. I am able to successfully login and navigate to the "friends' birthday" modal, but then I am unable to comment in the textbox.
Here is the error I am getting:
selenium.common.exceptions.NoSuchElementException:
Message: no such element: Unable to locate element:
{"method":"xpath","selector":"//*[#id="u_i_6"]"}
I haven't had any issues finding other page elements via XPath so I am not sure what is causing the issue. I also tried finding the textbox to comment via classname, but had the same result. Can anyone offer some thoughts?
EDIT: forgot to paste code
from selenium import webdriver
from pynput.keyboard import Key, Controller
import time
import config
# fetch facebook password from separate file in the same directory
pw = config.secret['pw']
keyboard = Controller()
driver = webdriver.Chrome()
options = webdriver.ChromeOptions()
options.add_argument('--disable-extensions')
options.add_argument('--disable-notifications')
# navigate to facebook url
driver.get('https://facebook.com')
# input email address
email_input = driver.find_element_by_xpath('//*[#id="email"]')
email_input.send_keys(<omitted>)
# input pw
password_input = driver.find_element_by_xpath('//*[#id="pass"]')
password_input.send_keys(pw)
# click login button element
login_button = driver.find_element_by_xpath('//*[#id="u_0_b"]')
login_button.click()
home_button = driver.find_element_by_xpath('//*[#id="u_0_c"]/a')
# wait 8 seconds for browser popup before pressing esc to get out
time.sleep(8)
keyboard.press(Key.esc)
# check if there are any birthdays today
birthday_section = driver.find_element_by_xpath('//*[#id="home_birthdays"]/div/div/div/div/a/div/div/span/span[1]')
birthday_section.click()
first_comment = driver.find_element_by_xpath('//*[#id="u_i_6"]')
first_comment.send_keys('happy birthday!')
# click post button to post comment
# close browser window after actions are complete
time.sleep(5)
driver.close()
It is hard to answer without the code, but here are a couple of ideas:
Make sure you are using some sort of Selenium wait, implicit or explicit, so your code does not search for an element before this element appears on the page. You can add this code after driver.get() for implicit wait:
driver.implicitly_wait(5)
Also, it looks like IDs are dynamic on that page, I get a different one on my FB page. Try using this xpath to find the textarea:
"//form[contains(#action, 'birthday')]//textarea"
Hope this is helpful, good luck!

Categories

Resources