Upload file - Make input visible (Error: ElementNotVisibleException) - python

Currently I have this input
<label class="bold grey-rectangle" data-uploading="Uploading" data-completed="Upload completed">
<span>+ Add certificate</span>
<input type="file" data-validation-allowing="jpg, jpeg, pdf" data-validation="mime" name="qualification2">
<div class="spinner hidden">
<div class="spinner-inner"></div>
</div>
</label>
and I want to send a file to the same, so I'm running the following codes:
self.driver.execute_script("document.getElementsByName('qualification2')[0].style.display='block';")
self.driver.find_element_by_name("qualification2").send_keys("certificate.jpeg")
but I'm getting the following error
ElementNotVisibleException: Message: Element is not currently visible and so may not be interacted with
How, effectively, I can do an upload with python and selenium?

You should try removing the hide class to make the element visible:
elm = self.driver.find_element_by_name("qualification2")
self.driver.execute_script('arguments[0].removeAttribute("class");', elm)
elm.send_keys("/absolute/path/to/certificate.jpeg")
Used the link you've provided, tested it:
from selenium import webdriver
driver = webdriver.Chrome()
driver.get("http://your/site")
elm = driver.find_element_by_name("qualification2")
driver.execute_script('arguments[0].removeAttribute("class");', elm)
elm.send_keys("/Users/user/Downloads/test.jpg")
Produced:
Note that in Firefox you would also have to reset the margin-left style property to 0 to make the element really visible:
driver.execute_script('arguments[0].removeAttribute("class"); arguments[0].style["margin-left"] = 0;', elm)

Related

Using selenium to click a dropdown menu within a secondary menu

I am using selenium to login to a website and load a dropdown menu. Inside this menu there is a secondary menu that has a link to download a csv file.
Using the following code, I can do all of those steps except click the option within the secondary menu:
driver.get(url)
driver.find_element(By.ID,"user_email").send_keys(user)
driver.find_element(By.ID,"user_password").send_keys(password)
driver.find_element(By.ID,"submit").click()
sleep(5)
driver.find_element(By.ID, "table-actions").click()
open_win_elem = driver.find_element(By.CLASS_NAME,"table-actions-menu-parent").click()
sleep(2)
driver.find_element(By.CLASS_NAME, "table-actions-menu-sub-option table-actions-option").click() #this is where the last click doesnt happen
When I inspect the dropdown menu item that I wish to click, it looks like this:
Download / Copy PlayerList
<div class="menu-top-options">
<div class="table-actions-option-radio-container">
<label><input type="radio" name="players-to-include" value="all" checked="">All Players</label>
<label><input type="radio" name="players-to-include" value="filtered">Filtered</label>
</div>
<label class="table-actions-option-checkbox"><input type="checkbox" name="include-grouped-columns-header" checked="">Include Grouped Columns Header</label>
</div>
<div class="table-actions-menu-sub-option table-actions-option" data-action="downloadPlayerlist">Download CSV Format<i class="csv-icon fas fa-file-csv"></i></div>
<div class="table-actions-menu-sub-option table-actions-option" data-action="downloadPlayerlistXLSX">Download XLSX Format<i class="excel-icon fas fa-file-excel"></i></div>
<div class="table-actions-menu-sub-option table-actions-option" data-action="copyPlayerlist">Copy to Clipboard<i class="copy-icon fas fa-copy"></i></div>
</div>
</div>
This returns the following error:
File "\AppData\Local\Programs\Python\Python310\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 243, in check_response
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"css selector","selector":".table-actions-menu-sub-option table-actions-option"}
Is there something else required to similate this particular click?
It looks like By.CLASS_NAME only takes one class name as an argument. https://selenium-python.readthedocs.io/locating-elements.html#locating-elements-by-class-name
Perhaps try using By.CSS_SELECTOR and making the argument a CSS selector that looks for both classes.
driver.find_element(By.CSS_SELECTOR, ".table-actions-menu-sub-option.table-actions-option").click()

Unable to click on an ahref link using Python Selenium

This is the html code:
<div id="dcf-page-export-buttons" class="no-print" style="display: block;">
<a id="dcf-saveaspdf" href="#" target="_blank" class="k-button">
Save as PDF
</a>
<a id="dcf-saveaspng" href="#" target="_blank" class="k-button">
Save as Image
</a>
<a id="dcf-printPdf" class="k-button" href="#">
Print
</a>
<a id="dcf-btnClose" class="k-button" href="#">
Close
</a>
</div>
I want to click on the Print href but it isn't being clicked. Here is my code:
exportLink = driver.find_element_by_link_text("Export")
exportLink.click()
print = driver.find_element_by_id("dcf-printPdf")
print.click()
Before finding element by id for print, I had clicked on Export href which opened a new tab and after opening of the new tab, I'm trying to click on print but getting an error. This is the error:
selenium.common.exceptions.ElementNotInteractableException: Message: element not interactable
Let me know if I'm going wrong somewhere or if there is a problem in the html.
The first part of the question has been answered. This is the 2nd part:
On clicking on this Print button:
This window gets opened. It's not a new tab per se, but just a new window. Within that window, I want to click on the Save button. Is there a way to go about doing that? This is how the view looks like:
And here is the html code.
<cr-button class="action-button" aria-disabled="false" role="button" tabindex="0">
Save
</cr-button>
Here is my code till now:
exportLink = driver.find_element_by_link_text("Export")
exportLink.click()
driver.switch_to.window(driver.window_handles[1])
driver.execute_script("document.getElementById('dcf-user-info').style.display = 'none';")
time.sleep(1)
print = driver.find_element_by_link_text("Print")
print.click()
This is the snip of the error log. I've added the snip because I'm unsure of the error.
Small continuation of the error:
You need to switch to new tab first then you can click on Print using that Id that you have been trying.
Switch to new windows like this :
driver.switch_to.window(driver.window_handles[1])
As you can see from the error, the element you trying to access is not interactable.
So, the problem is not with HTML.
I can't see the page you working on, but the problem can be that element you trying to access is out of the view.
Try this
from selenium.webdriver.common.action_chains import ActionChains
print = driver.find_element_by_id("dcf-printPdf")
ActionChains(driver).move_to_element(print).click(button).perform()

Why doesn't Selenium find element by name? (Python, Firefox)

I have the following HTML
<button name="_eventId_confirmed" class="btn btn-green margin-bottom-20 bold medium" autofocus="">
and the following Python
btn = driver.find_element_by_name('_eventId_confirmed')
Running this code returns an error
selenium.common.exceptions.NoSuchElementException: Message: Unable to locate element: [name="_eventId_confirmed"]
Just before this non-working HTML/code-combination I have the following HTML element:
<input name="registration" id="registration" class="size-28" maxlength="7" autofocus="" autocomplete="off" type="text" data-original-title="" title="" style="">
which I successfully access with
elem = driver.find_element_by_name("registration")
Why does the second one work but not the first one?
Edit: the problem was that a new window was opened and I needed to switch window handler. So, false alarm. Thank you all.
A "tag name" is not the same as a "name". The former refers to the HTML element's tag name, while the later refers to the HTML element's "name" attribute.
For example, in your first HTML snippet,
<button name="_eventId_confirmed" class="btn btn-green margin-bottom-20 bold medium" autofocus="">
button is the tag name while _eventId_confirmed is the (attribute) name.
This could be because of the modal dialogue, as you mentioned in a comment. Try
driver.switchTo().frame("ModalFrameTitle");
or
driver.switchTo().activeElement()
You can do it by using window_handles and switch_to_window method.
Before clicking the button the window handle as
window_before = driver.window_handles[0]
elem = driver.find_element_by_name("registration")
after clicking the button the window handle of newly opened window as
window_after = driver.window_handles[1]
then execute the switch to window methow to move to newly opened window
driver.switch_to.window(window_after)
driver.find_element_by_name("_eventId_confirmed").click()
Hope this help.

selenium python: how to send keys to a hidden password with differnet IDs

I'm currently using selenium with python 2.7 and I'm trying to to insert a password to the following form:
<tr id="mockpass">
<td>
<input type="text" value="something1" onfocus="document.getElementById('mockpass').style.display='none';
document.getElementById('realpass').style.display=''; document.getElementById('Irealpass').focus();">
</td>
</tr>
<tr id="realpass" style="display: none;">
<td>
<input type="password" name="Password" id="Irealpass" onblur="if(this.value=='') {document.getElementById('mockpass').style.display='';
document.getElementById('realpass').style.display='none';}">
</td>
</tr>
I tried using the following code but I keeping getting an error while trying to excute the clear command:
passBoxXpath='//*[#id="mockpass"]/td/input'
passBoxElement = WebDriverWait(driver, 10).until(lambda driver: driver.find_element_by_xpath(passBoxXpath))
passBoxElement.click()
passElement = WebDriverWait(driver, 10).until(lambda driver: driver.find_element_by_xpath('//*[#name="Password"]'))
passElement = driver.execute_script("arguments[0].style.display = 'block'; return arguments[0];",
passElement)
passElement.clear()
passElement.send_keys("myPassword")
The error:
raise exception_class(message, screen, stacktrace)
InvalidElementStateException: Message: Element is not currently interactable and may not be manipulated
I'm not sure if it's something to do with the focus or the blur that changes the element, but I get the element and fail to accsses it.
Thanks in advance!
update: the next line solved my case (still don't know why it didn't work):
driver.execute_script('document.getElementById("Irealpass").setAttribute("value","myPassword");')
In this way I didn't need to use the passBoxElement at all or changing the display style.
According to the docs http://selenium-python.readthedocs.io, this code should work.
elem = driver.find_element_by_css_selector("#mockpass input:first-child")
If you get the error anyway, scroll the browser window to element you are trying to access.
A couple things...
First off, if you are trying to perform user scenarios, you want to avoid using JavascriptExecutor (JSE). JSE allows you to do things on a page that an actual user cannot. Avoid using JSE unless you absolutely have to or if you don't care about user scenarios.
The problem is that the input that you want is hidden in the HTML you provided. You can see that in the 2nd TR, style="display: none;". If you look in the HTML of the first INPUT, you will see that the onfocus hides the first TR
onfocus="document.getElementById('mockpass').style.display='none';
and then unhides the 2nd TR
document.getElementById('realpass').style.display='';
So what you need to do is to focus the first INPUT which will expose the second INPUT.
One thing to note, from the JS in the second INPUT it looks like if you value is empty, it will rehide the second INPUT and expose the first (undoing what you just did).
onblur="if(this.value=='') {docum ...
I would do something like this
from selenium.webdriver.support import expected_conditions as EC
wait = WebDriverWait(driver, 10)
wait.until(EC.element_to_be_clickable(By.XPATH, '//*[#id="mockpass"]/td/input')).click()
wait.until(EC.element_to_be_clickable(By.XPATH, '//*[#id="Irealpass"]')).send_keys("myPassword")
Below should be work:
passwdEle = self.driver.find_element(by='id', value='Irealpass')
self.driver.execute_script('arguments[0].setAttribute("value","****")', passwdEle)

How to locate text input by name using Selenium WebDriver?

I'm a selenium newbie and just trying to learn the basics. I have a simple CherryPy webapp that takes a first name and last name as input:
My Webapp:
<p>
<label></label>
<input name="first_name"></input>
<br></br>
</p>
<p>
<label></label>
<input name="last_name"></input>
<br></br>
</p>
In my python console I have:
from selenium import webdriver
driver = webdriver.Firefox()
driver.get('http://localhost:8080')
The page loads fine in FF but I'm a little lost on how to get text into the 'first_name' and 'last_name' text boxes. I see examples where you do something like inputElement = driver.find_element_by_id("n") and then inputElement.send_keys('my_first_name') but I don't have an id...just a name. Do I need to add stuff to my web page? Thanks!
You can use find_element_by_name:
driver.find_element_by_name('first_name').send_keys("my_first_name")
driver.find_element_by_name('last_name').send_keys("my_last_name")

Categories

Resources