Selenium - Unable to find input elements inside iframe using SwitchTo() - python

I have a hard time locating two input elements of a specific website.
Well, as you can see above, "username" input element and "password" input element are inside an iframe with id = tab1.
So I tried (among other things) something like this:
driver = webdriver.Firefox()
driver.get('https://www.website.com/sites/en/Pages/default.aspx')
driver.SwitchTo().Frame(driver.FindElement(By.id("tab1")));
username = WebDriverWait(driver, 20).until(EC.visibility_of_element_located((By.XPATH, '//*[#id="login-form"]/div[1]/input')))
username.send_keys(credentials.username)
password = WebDriverWait(driver, 20).until(EC.visibility_of_element_located((By.XPATH, '//*[#id="login-form"]/div[2]/input')))
password.send_keys(credentials.password)
submit = WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, '//*[#id="loginBtn"]')))
action = ActionChains(driver)
action.move_to_element(submit).click().perform()
That is, I switched to frame "tab1" and then searched for the elements with their XPath. (Both full XPath and simple XPath).
But I get the following error again and again:
Process finished with exit code -1073740791 (0xC0000409)
without even activating "try-except" to show me something I can use for debugging.
Well, the question is: can I locate these elements somehow?
Thank you in advance.

wait=WebDriverWait(driver,10)
wait.until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR,"#tab1")))
You are using Java use Python instead and waits.
driver.SwitchTo().Frame(driver.FindElement(By.id("tab1")));
Imports:
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

Related

How to select an option from the non select dropdown list based on combobox using Python Selenium

Trying to automate one thing for my work, which was choosing one option from the dropdown list on the website below:
https://interparking-pl.my.site.com/abonament/s/?id=a0A58000000D7pZ
The Selenium automation didn't work in that case. After writing such code:
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
chrome_driver_path = r"C:/Users/.../Projects/chromedriver.exe"
service = Service(executable_path=chrome_driver_path)
driver = webdriver.Chrome(service=service)
driver.get("https://interparking-pl.my.site.com/abonament/s/?id=a0A58000000D7pZ")
wait = WebDriverWait(driver, 10)
abo_button = wait.until(EC.element_to_be_clickable((By.XPATH, '//*[#id="combobox-button-53"]')))
After executing I've got a message:
TimeoutException
In case of finding element by tag name or any other options, the following message pops up:
Message: no such element: Unable to locate element
The list is built on button tags and has a structure of lightning-basecombobox. It looks like there is no possibility to click on the dropdown list and choose the required option automatically.
Is it needed to do something different with such stuff?
What I expect is to use Selenium to choose between the options in the list.
The combobox is a <button> element.
Additionally the id i.e. combobox-button-53 is dynamically generated and is bound to chage sooner/later. They may change next time you access the application afresh or even while next application startup. So can't be used in locators.
Solution
To click 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:
driver.get("https://interparking-pl.my.site.com/abonament/s/?id=a0A58000000D7pZ")
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button[name='subscriptionsTypeId']"))).click()
Using XPATH:
driver.get("https://interparking-pl.my.site.com/abonament/s/?id=a0A58000000D7pZ")
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//button[#name='subscriptionsTypeId']"))).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
Browser Snapshot;
When I load the page, I get the element ID (XPATH) as following. //*[#id="combobox-button-51"]
Maybe the number 51 isn't always the same? In that case, try:
//*[starts-with(#id,'combobox-button-5')]
Or just use //*[#name="subscriptionsTypeId"] , as another answer here allready mentioned.

Selenium python - spotify page

Im trying to click a follow button on a spotify page with selenium but it wont work.
I've tried xpath and class_name but its not working.
The page im trying to click the follow button is page
Html Elemant:
<button type="button" class="aAr9nYtPsG7P2LRzciXc">Follow</button>
I think spotify randomizes the class names in order to prevent scrapping
My Code:
driver.find_element(By.XPATH, '//*[#id="main"]/div/div[2]/div[3]/main/div[2]/div[2]/div/div/div[2]/section/div/div[3]/div/button[1]').click()
Looks like you are simply missing a delay.
The best way to do that is to use Expected Conditions explicit waits.
Also your locator can be improved.
With the following inports
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
After instantiating the wait object with
wait = WebDriverWait(driver, 20)
Your click action could be performed with:
wait.until(EC.visibility_of_element_located((By.XPATH, "//button[text()='Follow']"))).click()
your code is fine.
but from my experience of "not getting an element from a page" the problem was that i didnt wait enough for the page to load.
try this:
from time import sleep
sleep(0.5) # or 1 second if its slower to load
driver.find_element(By.XPATH, '//*[#id="main"]/div/div[2]/div[3]/main/div[2]/div[2]/div/div/div[2]/section/div/div[3]/div/button[1]').click()
you dont have to wait 20 seconds, lol.
you just need some seconds before that element.
Instead of using XPATH, you can use cssSelector which is much simpler and direct
driver.implicitly_wait(20)
button = driver.find_element_by_css_selector("button[class=aAr9nYtPsG7P2LRzciXc]")
button.click()
Edit: since everyone mentioned about waiting I added the implicit wait
Note: no, the driver wont wait 20 seconds but it will immediately execute after finding the element. 20 seconds is the maximum time you let it search for the button.
The Follow element is a dynamic element.
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, "div[data-testid='action-bar-row'] > button:not(aria-label)"))).click()
Using XPATH:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//button[text()='Follow']"))).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

Python Selenium impossible, tried id, class can't find XPath

I am trying to enter a field with text (email), in the username box. However, it is not interacting with it. I have it in a try & except statement but it only spits out excepts.
Website is account.protonmail.com/signup
I have tried everything: xpath, class, id, but nothing works. I am losing my mind!
Password works fine:
Does not work:
driver.find_element_by_xpath('//*[#id="username"]').send_keys(password)
Does work:
driver.find_element_by_xpath('//*[#id="repeat-password"]').send_keys(password)
And yes, I do wait until JavaScript finishes running.
it is in iframe, and needs explicit waits :-
driver = webdriver.Chrome(driver_path)
driver.maximize_window()
driver.get("https://account.protonmail.com/signup")
wait = WebDriverWait(driver, 20)
wait.until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR, "iframe[sandbox^='allow-scripts']")))
ele = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "#username"))).send_keys('someemail#gmail.com')
Imports :
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
Element you are trying to access is inside an iframe. First you need to switch to the frame like this
driver.switch_to.frame(driver.find_element_by_xpath("//iframe[contains(#src,'account-api.protonmail.com')]"))
It's very difficult for you to write everything, make it easier
click = driver.find_element_by_xpath('//*[#id="username"]').click()
click.send_keys('')
click.send_keys(password)

Selenium: Element Click Intercepted while submitting a form

So I'm trying to submit a form but something is either preventing me from accessing the box or I'm using a wrong element but I think I'm using the correct one.
Here is my code:
from selenium import webdriver
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
driver = webdriver.Chrome(executable_path = 'mypath/chromedriver.exe')
driver.maximize_window()
#driver.implicitly_wait(50)
driver.get("https://ai.fmcsa.dot.gov/SMS")
wait = WebDriverWait(driver, 20)
wait.until(EC.element_to_be_clickable((By.XPATH, "//a[#title='Close']"))).click()
wait = WebDriverWait(driver, 20)
driver.find_element_by_xpath('//*[#id="home-body"]/div[1]/div/div[1]/form/label').click()
driver.find_element_by_xpath('//*[#id="home-body"]/div[1]/div/div[1]/form/label').send_keys('1818437')
driver.find_element_by_xpath('/html/body/div[3]/div[2]/article/section[2]/div[1]/div/div[1]/form/input[2]').click();
What I'm getting on the output is
ElementClickInterceptedException: Message: element click intercepted:
Element ... is
not clickable at point (553, 728). Other element would receive the
click:
(Session info: chrome=93.0.4577.63)
What might be the issue?
Things to noted down in this scenario :-
When you define an explicit waits wait = WebDriverWait(driver, 20), you can always use wait reference in the scope. you do not need to create again and again in same class.
Try to avoid absolute xpath /html/body/div[3]/div[2]/article/section[2]/div[1]/div/div[1]/form/input[2], try with relative xpath/xpath axes.
When we try to send keys to some element, in general it should be a input tag, not label
You may have to scroll, may be not in this case but when you scroll manually to interact with elements in UI, same has to automated with Selenium as well.
Also I observed to this webapp that search and input tags are duplicated, so I have used xpath indexing [2] to handle.
Sample code :-
driver = webdriver.Chrome(executable_path = 'mypath/chromedriver.exe')
driver.maximize_window()
#driver.implicitly_wait(50)
driver.get("https://ai.fmcsa.dot.gov/SMS")
wait = WebDriverWait(driver, 20)
wait.until(EC.element_to_be_clickable((By.XPATH, "//a[#title='Close']"))).click()
wait.until(EC.element_to_be_clickable((By.XPATH, "(//input[#name='MCSearch'])[2]"))).send_keys('1818437')
wait.until(EC.element_to_be_clickable((By.XPATH, "(//input[#name='search'])[2]"))).click()
You can use below xpaths too.
driver.find_element_by_xpath("//div[#class='sms-search-box']//input[1]").send_keys('1818437')
driver.find_element_by_xpath("//div[#class='sms-search-box']//input[2]").click()
Xpath you are using is not right. Your xpath for the input field should be like this.
driver.find_element_by_xpath("//input[#name='MCSearch' and #placeholder='Type Name or U.S. DOT#']").send_keys("1818437")
driver.find_element_by_xpath("//input[#placeholder='Type Name or U.S. DOT#']//following::input[#value='Search']").click();

How to find the Xpath of the element as per the html through Selenium and Python

Tried something like this in python unable I want to click on cross using Selenium.
driver.find_element_by_xpath("//span[contains(#onclick, 'parent.$WZRK_WR.closeIframe('60005','intentPreview');')]").click()
As per the HTML you have shared to click on the element depicted as X, first you need to induce WebDriverWait while switching to the <iframe> and again induce WebDriverWait for the desired element to be clickable and you can use the following solution:
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH,"//iframe[#id='wiz-iframe-intent']")))
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "//div[#class='CT_Interstitial']//span[#class='CT_InterstitialClose']"))).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
Open below URL and Click on Add to Chrome button.
Xpath Helper- https://chrome.google.com/webstore/detail/xpath-helper/hgimnogjllphhhkhlmebbmlgjoejdpjl?hl=en
Once plugin added to Chrome. Open your application/webpage and press SHIFT+CTRL+X. Black window will appear on top then you can play with xpath.
If xpath is invalid- then you will get xpath error and if no matches found then it will display NULL.
Note- To check element attribute still you can use F12 that is nothing but default inspect element for all browser then check attribute and create your own xpath and try.
Xpath Syntax
// tagname[#attribute-name=’value1′] and if you are not sure about tag name then no worry you can try with * also
//*[#attribute-name='value1']
You are dealing with an iframe. Follow below steps :
You'll need to switch control to iframe.
Then perform your action (in this case 'Click close').
Switch the control back to default frame.
You can try with this css_selector :
div.CT_InterstitialContents+span.CT_InterstitialClose[onclick]
Xpath would be :
//div[#class='CT_InterstitialContents']/following-sibling::span[#class='CT_InterstitialClose' and onclick]
Try to use this xPath:
//div[#id = 'contentDiv']/div/div/span[#class = 'CT_InterstitialClose']
Code:
close_btn = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "//div[#id = 'contentDiv']/div/div/span[#class = 'CT_InterstitialClose']")))
close_btn.click()
Imports:
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.common.by import By
Explanation:
WebDriverWait is used to wait until element will be clickable, and only then clicks on it. In this example WebDriverWait will wait at least 10 seconds until element will be clickable.
PS: as I see in the screenshot your element is probably in iframe. That means you have to switch to this iframe first, to be able to interact with the elements in it. The code sample for it would be like this:
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH, "XPATH_TO_FRAME")))
# do stuff
close_btn = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "//div[#id = 'contentDiv']/div/div/span[#class = 'CT_InterstitialClose']")))
close_btn.click()
# switch back to default content
driver.switch_to.default_content()
You can write xpath using class name of span. Please refer an example below.
//span[#class='amountCharged']

Categories

Resources