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()
Related
A selenium newbie here. I'm trying to use Selenium to automate download of CSV file from calltools and upload it to salesforce. Here is the UI for the dropdown menu for selecting the options before exporting the CSV.
The HTML for the same is:
<div _ngcontent-rnw-c215="" style="">
<label _ngcontent-rnw-c215="">Templates</label>
<br _ngcontent-rnw-c215="">
<select _ngcontent-rnw-c215="" class="ng-pristine ng-valid ng-touched">
<option _ngcontent-rnw-c215="" value="0: null"></option>
<option _ngcontent-rnw-c215="" value="1: Agent KPI" class="ng-star-inserted"
style="" xpath="1">Agent KPI</option>
<option _ngcontent-rnw-c215="" value="2: Payroll" class="ng-star-
inserted">Payroll</option>
<option _ngcontent-rnw-c215="" value="3: Agent Status" class="ng-star-
inserted">Agent Status</option>
<!---->
</select>
I have tried multiple ways to access the appropriate option (1. Agent KPI). My code so far is
WebDriverWait(driver, 30).until(
EC.element_to_be_clickable((By.XPATH, "//select[#class='ng-valid ng-touched ng-dirty']//option[#value='1: Agent KPI']"))
).click()
The other approach tried is:
driver.find_element(By.XPATH, "//select[#class='ng-valid ng-touched ng-dirty']//option[#value='1: Agent KPI']")
All these options are resulting in:
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":"//select[#class='ng-valid ng-touched ng-dirty']"}
But this didn't work either. I used implicit wait as well but I am getting the same error. I checked the HTML and there's no iframe within the same. I have been using selectorhub to retrieve XPATHs of elements so pretty sure they're correct. I also used CSS selectors and tag names but still stuck on the same.
I looked everywhere but despite the various threads and answers, I'm still stuck on this issue. Could anyone advise me on what's going wrong here?
Thanks!
It seems you are nearly there. If I take the reference of your page element I can see the class name you have provided seems wrong.
Try this below xpath.
WebDriverWait(driver, 30).until(
EC.element_to_be_clickable((By.XPATH, "//select[#class='ng-pristine ng-valid ng-touched']//option[#value='1: Agent KPI']"))
).click()
I am using selenium and python to learn about automation web testing.
I want to click on "Continue" button, while there is only span in it (I had learned that using id instead of span is so much easier)
but in this case, I want to click the span.
I am using below code:
driver.find_element_by_xpath("//span[contains(#class,'mdBtn01Txt')][contains(text(),'Continue')]").click()
here is the element :
<div class="mdLYR12Inner01">
<a class="MdBtn01 mdBtn01 ExDisabled FnSubmitBtn" style="display:none" href="#" onclick="charge(this); return false;">
<span class="mdBtn01Inner">
<span class="mdBtn01Txt">
Continue <<<(I want to click this button)
</span>
</span>
</a>
</div>
</footer>
But, I got this message below:
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":"//span[contains(#class,'mdBtn01Txt')][contains(text(),'Continue')]"}
Does not looks like a valid xpath, correct one should be
//span[#class='mdBtn01Txt']
Here is the rule to create xpath
Syntax for XPath:
XPath contains the path of the element situated at the web page. Standard syntax for creating XPath is:
Xpath=//tagname[#attribute='value']
Tagname: Tagname of the particular node.
#: Select attribute.
Attribute: Attribute name of the node.
Value: Value of the attribute.
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.
I'm using SeleniumLibrary for Robot Framework and i do have an issue regarding of Input Text function:
HTML:
<div class="form-group">
<label class="col-sm-6 control-label" for="gngFeeValue" >What is the expected Fee Value?</label>
<div class="col-sm-4">
<input id="gngFeeValue" data-role="numerictextbox"
data-format="###,###,###,###,###,##0"
data-decimals="0"
data-spinners="false"
data-bind="value: gng.feeValue, disabled: isInputDisabled" placeholder="Enter fee value" />
</div>
</div>
TEST.robot:
Expected Fee Value - Value
[Arguments] ${expectedFeeValue}
Input Text //*[#id="gngFeeValue"] ${expectedFeeValue}
I do get an error:
InvalidElementStateException: Message: invalid element state: Element is not currently interactable and may not be manipulated
Anyone who could help me regarding this? Thanks!
I had the same problem. I couldn't find any elements on a specific form.
I realized that I could use the elements outside the form normally. So I started investigating html and found that it was inside an iframe.
To solve this, I only needed the SeleniumLibrary Select Frame:
Select Frame xpath=//*[#id="iframe"]
The webElement your are trying to interact with is either not clickable or it is disabled or may be it is out of browser's viewport. Selenium API is successful only on active interact-able webelements. Use Javascript, as a last mile solution.
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)