I am trying to access the "events" inside the div with class name "rps-wrapper" within the url http://gridworlds-multiplayer.org/ but when I use the function I get an error.
<div class="rps-wrapper">
<ul id="events"></ul>
<div class="controls">
<div class="chat-wrapper">
<form id="chat-form">
<input id="chat" autocomplete="off" title="chat"/>
<button id="say">Say</button>
</form>
</div>
</div>
</div>
<script src="/socket.io/socket.io.js"></script>
<script src="src/client.js"></script>
</body>
from selenium import webdriver
driver = webdriver.Chrome()
driver.get('*the site is here*')
rps_wrapper = driver.find_element_by_class_name('rps-wrapper')
Should get the div with class name rps-wrapper, but outputs error elenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"css selector","selector":".rps-wrapper"}
(Session info: chrome=75.0.3770.142)
To locate the events within the <div> with class name rps-wrapper as the desired element is within an <frame> so you have to:
Induce WebDriverWait for the desired frame to be available and switch to it.
Induce WebDriverWait for the desired element to be clickable.
You can use either ofthe following Locator Strategies:
Using CSS_SELECTOR:
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.TAG_NAME,"frame")))
rps_wrapper = WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.CSS_SELECTOR, "div.rps-wrapper>ul#events")))
Using XPATH:
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.TAG_NAME,"frame")))
rps_wrapper = WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.XPATH, "//div[#class='rps-wrapper']/ul[#id='events']")))
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
Here you can find a relevant discussion on Ways to deal with #document under iframe
Related
I am trying to click a button on a website in Python using Selenium. The html looks like this:
<a class="btn btn-default btn-lg primary-light-blue-btn" onclick="createReport()">Create report</a>
I have tried using:
l = driver.find_element(By.XPATH, "//button[#class='btn btn-default btn-lg primary-light-blue-btn']")
But I get the error:
NoSuchElementException: no such element: Unable to locate element: {"method":"xpath","selector":"//button[#class='btn btn-default btn-lg primary-light-blue-btn']"}
I have also tried other things, but it just won't find the button. E.g.:
l = driver.find_element(By.XPATH, "//button[text()='Create report']")
I have also tried introducing a wait, but that does not help, e.g.:
l = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "//button[text()='Create report']")))
change the tag //button to //a:
l = driver.find_element(By.XPATH, "//a[#class='btn btn-default btn-lg primary-light-blue-btn']")
As per the given HTML:
<a class="btn btn-default btn-lg primary-light-blue-btn" onclick="createReport()">Create report</a>
The element is a <a> tag.
Solution
To click on the element with text as Create report you can use either of the following locator strategies:
Using link_text:
driver.find_element(By.LINK_TEXT, "Create report").click()
Using css_selector:
driver.find_element(By.CSS_SELECTOR, "a.btn.btn-default.btn-lg.primary-light-blue-btn[onclick^='createReport']").click()
Using xpath:
driver.find_element(By.XPATH, "//a[#class='btn btn-default btn-lg primary-light-blue-btn' and starts-with(#onclick, 'createReport')]").click()
Ideally to click on the clickable element you need to induce WebDriverWait for the element_to_be_clickable() and you can use either of the following locator strategies:
Using LINK_TEXT:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.LINK_TEXT, "Create report"))).click()
Using CSS_SELECTOR:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "a.btn.btn-default.btn-lg.primary-light-blue-btn[onclick^='createReport']"))).click()
Using XPATH:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//a[#class='btn btn-default btn-lg primary-light-blue-btn' and starts-with(#onclick, 'createReport')]"))).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
Following is HTML code. I want to click on Export to CSV.
<pre>
<div id="leo-title-bar" style="width: 100%">
<div class="container-fluid p-0"><div class="no-gutters" style="min-height: 100vh;">
<div class="col-12 d-flex flex-column">
<nav class="navbar navbar-dark bg-primary justify-content-start" style="height: 64px; flex-wrap: unset;">
<span class="navbar-brand" style="flex: 1 1 0%; font-size: 22px;">Agency Summary</span>
<svg aria-labelledby="svg-inline--fa-title-5AhAR2Z9sKF8" data-prefix="fas" data-icon="download" class="svg-inline--fa fa-download fa-w-16 svg-shadow svg-icon-basic svg-icon-basic-hover" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
<title id="svg-inline--fa-title-5AhAR2Z9sKF8">Export to CSV</title>
<path fill="currentColor" d="M216 0h80c13....."></path></svg>
</div></main>
</div>
</div>
</div>
</div>
</pre>
I have tried following code:
from selenium import webdriver
driver = webdriver.Edge(PATH)
driver.find_element_by_xpath('//div[#class="col-12 d-flex flex-column"]/*[name()="svg"][#aria-labelledby="svg-inline--fa-title-5AhAR2Z9sKF8"]').click()
Getting an error:
selenium.common.exceptions.NoSuchElementException
Possibly you are missing a delay.
So adding some dummy sleep like
from selenium import webdriver
import time
driver = webdriver.Edge(PATH)
time.sleep(5)
driver.find_element_by_xpath('//div[#class="col-12 d-flex flex-column"]/*[name()="svg"][#aria-labelledby="svg-inline--fa-title-5AhAR2Z9sKF8"]').click()
Should resolve your problem.
Also your locator looks bad. You have to create more reliable locator.
Also you should use Expected Conditions explicit waits, as following:
from selenium import webdriver
import time
rom selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
driver = webdriver.Edge(PATH)
wait = WebDriverWait(driver, 20)
wait.until(EC.visibility_of_element_located((By.XPATH, '//div[#class="col-12 d-flex flex-column"]/*[name()="svg"][#aria-labelledby="svg-inline--fa-title-5AhAR2Z9sKF8"]'))).click()
Change
.../*[name()="svg"]...
to
.../*[local-name()="svg"]...
in your XPath-expression, because your <svg...> element is in the namespace xmlns="http://www.w3.org/2000/svg". Thing is that name() matches namespace:name, but local-name() only matches the name without the namespace(-prefix).
The desired element is a svg element. To click() on the element you have 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#leo-title-bar svg[data-icon='download']"))).click()
Using XPATH:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//div[#id='leo-title-bar']//*[name()='svg' and #data-icon='download']"))).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
References
You can find a couple of relevant discussions on interacting with SVG element in:
How to access to 'rect' type element through Selenium-Python
Clicking on svg using selenium python
Here is the HTML:
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<div class="modal-content">
<div class="modal-header">
<h5 id="add-title" class="modal-title">Add a text</h5>
<button type="button" class="close" data-dismiss="modal">×</button>
</div>
<section id="add-popup-card-body">
<form id="add-form"><div class="sm-form modal-body">
<h6 id="add-popup-card-body-subtitle" class="card-subtitle mb-2 text-muted">Please enter text</h6>
<input type="text" id="add-input-form" class="sm-form modal-body form-control validate" pattern="\S+" style="text-transform:uppercase" maxlength="32" placeholder="tag" onkeyup="this.value = this.value.toUpperCase();" required="">
<div><small>*Spaces are not allowed</small></div>
</div>`enter code here`
<div class="modal-footer justify-content-center">
<input type="submit" class="btn btn-primary">
</div></form>
</section>
</div>
</body>
</html>
All that I need is to find a way to make Selenium test close the modal. I have tried these so far and none worked:
self.driver.findElement(By.className("close")).click()
self.driver.findElement(By.xpath("//button[#class = 'close']")).click()
self.driver.find_element(By.CSS_SELECTOR, 'button[class="close"]').click()
There are basically 4 ways to click in Selenium.
I will use this xpath
//button[#class='close' and #data-dismiss='modal' and text()='×']
Code trial 1:
time.sleep(5)
driver.find_element_by_xpath("//button[#class='close' and #data-dismiss='modal' and text()='×']").click()
Code trial 2:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//button[#class='close' and #data-dismiss='modal' and text()='×']"))).click()
Code trial 3:
time.sleep(5)
button = driver.find_element_by_xpath("//button[#class='close' and #data-dismiss='modal' and text()='×']")
driver.execute_script("arguments[0].click();", button)
Code trial 4:
time.sleep(5)
button = driver.find_element_by_xpath("//button[#class='close' and #data-dismiss='modal' and text()='×']")
ActionChains(driver).move_to_element(button).click().perform()
Imports:
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.action_chains import ActionChains
PS : 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 and see, if your desired element is getting highlighted with 1/1 matching node.
To click on the element you can use either of the following Locator Strategies:
Using css_selector:
driver.find_element(By.CSS_SELECTOR, "button.close[data-dismiss='modal']").click()
Using xpath:
driver.find_element(By.XPATH, "//button[#class='close' and #data-dismiss='modal'][text()='×']").click()
Ideally, as the desired element is a Modal Dialog Box to click on the clickable 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, "button.close[data-dismiss='modal']"))).click()
Using XPATH:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//button[#class='close' and #data-dismiss='modal'][text()='×']"))).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
Thanks for the help. I have tried all the above solution but none worked. I was getting similar errors. After some reading I called an id that was above the "modal-content" and added 3 div . By using this code :
self.driver.find_element_by_xpath("//*[#id='add-tag popup']/div/div/div/button").click()
How can I send a click to the following elements using Selenium?
Note: They are placed at the same page and both of them have the same class "btn btn-primary"
<button class="btn btn-primary" data-ng-click="ctrl.findInstrumentsBySearch(ctrl.filterInstrument);" data-ng-disabled="ctrl.disableButtonSearchInstrument();">
<span class="fa fa-search"></span> Pesquisar
</button>
<button class="btn btn-primary" data-ng-click="ctrl.downloadLimitInstrumentCsv(ctrl.filterInstrument,{ filename: "export.csv" });">
<span class="fa fa-file-excel-o"></span> Exportar
</button>
When I try to use the following I receive the error "IndexError: list index out of range":
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
browser = webdriver.Chrome()
browser.get(("https://line.bvmfnet.com.br/#/limits/1"))
python_button = browser.find_elements_by_xpath("//button[#class='btn btn-primary' and #data-ng-click='ctrl.findInstrumentsBySearch(ctrl.filterInstrument)']")[0]
python_button.click()
To click on the elements with text as save you can use either of the following Locator Strategies:
Pesquisar:
Using css_selector:
driver.find_element_by_css_selector("button.btn.btn-primary[data-ng-click*='findInstrumentsBySearch'][data-ng-disabled*='disableButtonSearchInstrument']").click()
Using xpath:
driver.find_element_by_xpath("//button[#class='btn btn-primary' and contains(#data-ng-click, 'findInstrumentsBySearch')][contains(., 'Pesquisar')]").click()
Ideally, 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:
Exportar:
Using CSS_SELECTOR:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button.btn.btn-primary[data-ng-click*='downloadLimitInstrumentCsv']"))).click()
Using XPATH:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//button[#class='btn btn-primary' and contains(#data-ng-click, 'downloadLimitInstrumentCsv')][contains(., 'Exportar')]"))).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
Below is the HTML code and how to select element wither by using xpath or css selector
<button class="btn btn-sm ng-pristine ng-untouched ng-valid ng-empty" ng-repeat="ext in _view.getNonEmptyChildren()" ng-click="_navigate(ext.$id, _route.objectId, { 'navigator' : _route.navigator,
'relatedItemParentId': relatedItemParentId(ext.$parent)})" ng-class="{active: _view.getSelectedChild().$id == ext.$id}" ng-model="radioModel" btn-radio="'{ext[nameField]}'" aria-invalid="false">Clusters</button>
The desired element is an Angular element so you have to induce WebDriverWait for the desired element to be clickable and you can use either of the following solutions:
Using CSS_SELECTOR:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button.btn.btn-sm.ng-pristine.ng-untouched.ng-valid.ng-empty[ng-model='radioModel'][ng-class*='getSelectedChild']"))).click()
Using XPATH:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//button[#class='btn btn-sm ng-pristine ng-untouched ng-valid ng-empty' and #ng-model='radioModel'][contains(.,'Clusters')]"))).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