I'm trying to play QWOP using Selenium on Chrome but I keep getting the following error:
selenium.common.exceptions.NoSuchElementException:
Message: no such element: Unable to locate element
{"method":"id","selector":"window1"
(Session info: chrome=63.0.3239.108
(Driver info: chromedriver=2.34.522913
(36222509aa6e819815938cbf2709b4849735537c), platform=Linux 4.10.0-42-generic x86_64)
while using the following code:
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
import time
browser = webdriver.Chrome()
browser.set_window_size(640, 480)
browser.get('http://www.foddy.net/Athletics.html?webgl=true')
browser.implicitly_wait(10)
canvas = browser.find_element_by_id("window1")
canvas.click()
while (True):
action = ActionChains(browser)
action.move_to_element(canvas).perform()
canvas.click()
canvas.send_keys("q")
The same code works perfectly on Firefox, but because I want to use chrome's capability to run an webgl game in headless mode I can't really switch to Firefox.
Any workarounds to get this working?
NoSuchElementException
selenium.common.exceptions.NoSuchElementException popularly known as NoSuchElementException is defined as :
exception selenium.common.exceptions.NoSuchElementException(msg=None, screen=None, stacktrace=None)
NoSuchElementException is basically thrown in 2 cases as follows :
When using :
webdriver.find_element_by_*("expression")
//example : my_element = driver.find_element_by_xpath("xpath_expression")
When using :
element.find_element_by_*("expression")
//example : my_element = element.find_element_by_*("expression")
As per the API Docs just like any other selenium.common.exceptions, NoSuchElementException should contain the following parameters :
msg, screen, stacktrace
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":".//*[#id='create-portal-popup']/div[4]/div[1]/button[3]"}
(Session info: chrome=61.0.3163.100)
(Driver info: chromedriver=2.32.498550 (9dec58e66c31bcc53a9ce3c7226f0c1c5810906a),platform=Windows NT 10.0.10240 x86_64)
Reason
The reason for NoSuchElementException can be either of the following :
The Locator Strategy you have adopted doesn't identifies any element in the HTML DOM.
The Locator Strategy you have adopted is unable to identify the element as it is not within the browser's Viewport.
The Locator Strategy you have adopted identifies the element but is invisible due to presence of the attribute style="display: none;".
The Locator Strategy you have adopted doesn't uniquely identifies the desired element in the HTML DOM and currently finds some other hidden / invisible element.
The WebElement you are trying to locate is within an <iframe> tag.
The WebDriver instance is looking out for the WebElement even before the element is present/visibile within the HTML DOM.
Solution
The solution to address NoSuchElementException can be either of the following :
Adopt a Locator Strategy which uniquely identifies the desired WebElement. You can take help of the Developer Tools (Ctrl+Shift+I or F12) and use Element Inspector.
Here you will find a detailed discussion on how to inspect element in selenium3.6 as firebug is not an option any more for FF 56?
Use execute_script() method to scroll the element in to view as follows :
elem = driver.find_element_by_xpath("element_xpath")
driver.execute_script("arguments[0].scrollIntoView();", elem)
Here you will find a detailed discussion on Scrolling to top of the page in Python using Selenium
Incase element is having the attribute style="display: none;", remove the attribute through executeScript() method as follows :
elem = driver.find_element_by_xpath("element_xpath")
driver.execute_script("arguments[0].removeAttribute('style')", elem)
elem.send_keys("text_to_send")
To check if the element is within an <iframe> traverse up the HTML to locate the respective <iframe> tag and switchTo() the desired iframe through either of the following methods :
driver.switch_to.frame("iframe_name")
driver.switch_to.frame("iframe_id")
driver.switch_to.frame(1) // 1 represents frame index
Here you can find a detailed discussion on How can I select a html element no matter what frame it is in in selenium?.
If the element is not present/visible in the HTML DOM immediately, induce WebDriverWait with expected_conditions set to proper method as follows :
To wait for presence_of_element_located :
element = WebDriverWait(driver, 20).until(expected_conditions.presence_of_element_located((By.XPATH, "element_xpath']")))
To wait for visibility_of_element_located :
element = WebDriverWait(driver, 20).until(expected_conditions.visibility_of_element_located((By.CSS_SELECTOR, "element_css")
To wait for element_to_be_clickable :
element = WebDriverWait(driver, 20).until(expected_conditions.element_to_be_clickable((By.LINK_TEXT, "element_link_text")))
This Usecase
You are seeing NoSuchElementException because the id locator doesn't identifies the canvas uniquely. To identify the canvas and click() on it you have to wait for the canvas to be clickable and to achieve that you can use the following code block :
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//canvas[#id='window1']"))).click()
Reference
You can find Selenium's java client based relevant discussion in:
NoSuchElementException, Selenium unable to locate element
Related
Here is my code:
from selenium import webdriver
user = "someemail#email.com"
browser = webdriver.Chrome("/path/to/browser/")
browser.get("https://www.quora.com/")
username = browser.find_element_by_name("email")
browser.implicitly_wait(10)
username.send_keys(user)
Here is the error message:
selenium.common.exceptions.ElementNotInteractableException: Message: element not interactable
I think there is another thread with a similar issue. Either the solutions in that thread didn't work for me or I don't know how to implement the solutions.
find_element_by_name("email")
is present multiple times in DOM. So that wouldn't work.
You can try with this css selector :
input[class*='header_login_text_box'][name='email']
Code :
username = browser.find_element_by_css_selector("input[class*='header_login_text_box'][name='email']")
username.send_keys("user#gmail.com")
To send a character sequence to the Email field within Login section of Quora you need to induce WebDriverWait for the element to be clickable and you can use the following solution:
Code Block:
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
options = webdriver.ChromeOptions()
options.add_argument("start-maximized")
options.add_argument("--disable-extensions")
# options.add_argument('disable-infobars')
driver = webdriver.Chrome(chrome_options=options, executable_path=r'C:\Utility\BrowserDrivers\chromedriver.exe')
driver.get("https://www.quora.com/")
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//div[#class='title login_title' and text()='Login']//following::div[1]//input[#class='text header_login_text_box ignore_interaction']"))).send_keys("someemail#email.com")
Browser Snapshot:
As said in comment, the locator used returning two elements and required element is second one. driver trying to interact with first element, so exception is throwing.
good see in console, the locator returning required one or not.
> $$("[name='email']") (2) [input#__w2_wD9e9Qgz12_email.text, input#__w2_wD9e9Qgz18_email.text.header_login_text_box.ignore_interaction]
> 0: input#__w2_wD9e9Qgz12_email.text 1:
> input#__w2_wD9e9Qgz18_email.text.header_login_text_box.ignore_interaction
> length: 2
> __proto__: Array(0)
go for another locator, if not able to figure it out another locator, then comment, will help you.
from selenium import webdriver
user = "someemail#email.com"
browser = webdriver.Chrome("/path/to/browser/")
browser.get("https://www.quora.com/")
username = browser.find_element_by_xpath("//input[#class='text header_login_text_box ignore_interaction' and #type='text']")
browser.implicitly_wait(10)
username.send_keys(user)
Here You can find Why ElementNotInteractableException occurs.
If you are using the Select aproach like:
from selenium.webdriver.support.select import Select
try this
Select(WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, '''//*[#id="ReportViewer1_ctl04_ctl07_ddValue"]''')))).select_by_visible_text(str(x))
I'm using selenium. The source code of the element is:
<input tabindex="5" class="buttonStyle" onclick="submitForm('SEARCH','');return false" type="submit" value="Search">
The css shows
input[type='submit']
The code I use:
driver.find_element_by_xpath("//input[#type='submit']").click();
driver.find_element_by_css_selector("input[type='submit']").click()
Both don't work as expected.
The code below does not work as well:
driver.find_element_by_xpath("//a[#onclick='submitForm('SEARCH','');return false']").click()
InvalidSelectorException: Message: Unable to locate an element with the xpath expression //a[#onclick='submitForm('SEARCH','');return false'] because of the following error:
Error: Bad token, expected: ] got: SEARCH
I used the XPATH checker on internet explorer (the favourite page named MRI). It shows the target element. However the above code does not work.
I'm using Jupyter Notebook, Selenium and Internet Explorer (the page can only be opened in IE)
The error shows that the given XPATH is not valid. You seem to have an extra ']' in the xpath. Please update it.
wait = WebDriverWait(driver, 20)
button = wait.until(EC.element_to_be_clickable((By.XPATH, "//input[#type='submit']")))
button.click()
Add below imports to your solution
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
I currently have a selenium python script that is working with PhantomJS, but not Firefox. I get this error:
NoSuchElementException('Unable to locate element: Research Project', None, None)
Specifically, it fails on this line of code:
self.webdriver.find_element_by_link_text("Research Project").click()
I've tried some different wait methods with no luck, such as:
WebDriverWait(self.webdriver, 10000).until(EC.presence_of_element_located((By.LINK_TEXT, "Research Project")))
I've also tried using various Xpaths to test if the link text isn't specific enough, which resulted in an ElementNotInteractableException if no wait was implemented, or the wait timing out if implemented.
If it helps, my PhantomJS webdriver is defined as:
args = [
'--ignore-ssl-errors=true',
'--ssl-protocol=any',
'--web-security=false'
]
driver = webdriver.PhantomJS(service_args=args, executable_path='/usr/bin/phantomjs', service_log_path='/tmp/ghostdriver.log')
And my Firefox webdriver is simply defined as:
driver = webdriver.Firefox(executable_path='/usr/local/Cellar/geckodriver/0.21.0/bin/geckodriver')
I can provide more detail if necessary. Any help would be greatly appreciated.
The HTML for the object I'm trying to reference:
<div id="dynaTempSelView:dynaTempSelForm:tree_selector:newLinksDT:0:closeTree" style="padding-left:20px;" class="unselectedDiv"><img src="/converis/javax.faces.resource/images/collapsible_panel_triangle_state_expanded.png.xhtml?ln=intern" alt=""><span style="padding-left:15px;">Research Project </span></div><span id="dynaTempSelView:dynaTempSelForm:tree_selector:newLinksDT:0:hiddenDescriptiontree_closed" style="display: none;">Research Project</span>
The relevant HTML would have been helpful to decide on the Locator Strategy. Still, as per your code trials, moving forward as you are trying to invoke click() method so instead of using presence_of_element_located() you need to use element_to_be_clickable() as follows:
LINK_TEXT:
WebDriverWait(self.webdriver, 20).until(EC.element_to_be_clickable((By.LINK_TEXT, "Research Project"))).click()
PARTIAL_LINK_TEXT:
WebDriverWait(self.webdriver, 20).until(EC.element_to_be_clickable((By.PARTIAL_LINK_TEXT, "Research Project"))).click()
XPATH:
WebDriverWait(self.webdriver, 20).until(EC.element_to_be_clickable((By.XPATH, "//a[contains(.,'Research Project')]"))).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
I'm trying to play QWOP using Selenium on Chrome but I keep getting the following error:
selenium.common.exceptions.NoSuchElementException:
Message: no such element: Unable to locate element
{"method":"id","selector":"window1"
(Session info: chrome=63.0.3239.108
(Driver info: chromedriver=2.34.522913
(36222509aa6e819815938cbf2709b4849735537c), platform=Linux 4.10.0-42-generic x86_64)
while using the following code:
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
import time
browser = webdriver.Chrome()
browser.set_window_size(640, 480)
browser.get('http://www.foddy.net/Athletics.html?webgl=true')
browser.implicitly_wait(10)
canvas = browser.find_element_by_id("window1")
canvas.click()
while (True):
action = ActionChains(browser)
action.move_to_element(canvas).perform()
canvas.click()
canvas.send_keys("q")
The same code works perfectly on Firefox, but because I want to use chrome's capability to run an webgl game in headless mode I can't really switch to Firefox.
Any workarounds to get this working?
NoSuchElementException
selenium.common.exceptions.NoSuchElementException popularly known as NoSuchElementException is defined as :
exception selenium.common.exceptions.NoSuchElementException(msg=None, screen=None, stacktrace=None)
NoSuchElementException is basically thrown in 2 cases as follows :
When using :
webdriver.find_element_by_*("expression")
//example : my_element = driver.find_element_by_xpath("xpath_expression")
When using :
element.find_element_by_*("expression")
//example : my_element = element.find_element_by_*("expression")
As per the API Docs just like any other selenium.common.exceptions, NoSuchElementException should contain the following parameters :
msg, screen, stacktrace
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":".//*[#id='create-portal-popup']/div[4]/div[1]/button[3]"}
(Session info: chrome=61.0.3163.100)
(Driver info: chromedriver=2.32.498550 (9dec58e66c31bcc53a9ce3c7226f0c1c5810906a),platform=Windows NT 10.0.10240 x86_64)
Reason
The reason for NoSuchElementException can be either of the following :
The Locator Strategy you have adopted doesn't identifies any element in the HTML DOM.
The Locator Strategy you have adopted is unable to identify the element as it is not within the browser's Viewport.
The Locator Strategy you have adopted identifies the element but is invisible due to presence of the attribute style="display: none;".
The Locator Strategy you have adopted doesn't uniquely identifies the desired element in the HTML DOM and currently finds some other hidden / invisible element.
The WebElement you are trying to locate is within an <iframe> tag.
The WebDriver instance is looking out for the WebElement even before the element is present/visibile within the HTML DOM.
Solution
The solution to address NoSuchElementException can be either of the following :
Adopt a Locator Strategy which uniquely identifies the desired WebElement. You can take help of the Developer Tools (Ctrl+Shift+I or F12) and use Element Inspector.
Here you will find a detailed discussion on how to inspect element in selenium3.6 as firebug is not an option any more for FF 56?
Use execute_script() method to scroll the element in to view as follows :
elem = driver.find_element_by_xpath("element_xpath")
driver.execute_script("arguments[0].scrollIntoView();", elem)
Here you will find a detailed discussion on Scrolling to top of the page in Python using Selenium
Incase element is having the attribute style="display: none;", remove the attribute through executeScript() method as follows :
elem = driver.find_element_by_xpath("element_xpath")
driver.execute_script("arguments[0].removeAttribute('style')", elem)
elem.send_keys("text_to_send")
To check if the element is within an <iframe> traverse up the HTML to locate the respective <iframe> tag and switchTo() the desired iframe through either of the following methods :
driver.switch_to.frame("iframe_name")
driver.switch_to.frame("iframe_id")
driver.switch_to.frame(1) // 1 represents frame index
Here you can find a detailed discussion on How can I select a html element no matter what frame it is in in selenium?.
If the element is not present/visible in the HTML DOM immediately, induce WebDriverWait with expected_conditions set to proper method as follows :
To wait for presence_of_element_located :
element = WebDriverWait(driver, 20).until(expected_conditions.presence_of_element_located((By.XPATH, "element_xpath']")))
To wait for visibility_of_element_located :
element = WebDriverWait(driver, 20).until(expected_conditions.visibility_of_element_located((By.CSS_SELECTOR, "element_css")
To wait for element_to_be_clickable :
element = WebDriverWait(driver, 20).until(expected_conditions.element_to_be_clickable((By.LINK_TEXT, "element_link_text")))
This Usecase
You are seeing NoSuchElementException because the id locator doesn't identifies the canvas uniquely. To identify the canvas and click() on it you have to wait for the canvas to be clickable and to achieve that you can use the following code block :
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//canvas[#id='window1']"))).click()
Reference
You can find Selenium's java client based relevant discussion in:
NoSuchElementException, Selenium unable to locate element
Expected [object Undefined] undefined to be a string,
The code I am using is following:
System.setProperty("webdriver.gecko.driver","E:\\Software\\geckodriver-
v0.16.1-win64\\geckodriver.exe");
WebDriver wd= new FirefoxDriver();
wd.get("https://www.google.co.in/");
//wd.findElement(By.xpath(".//*
[#id='gbw']/div/div/div[1]/div[1]/a")).click();
wd.findElement(By.linkText("Gmail")).click();
WebElement e1= wd.findElement(By.xpath("//input[#id='identifierId']"));
e1.sendKeys("abc#gmail.com");
wd.findElement(By.xpath("//div[#id='identifierNext']/content/span[text()='Ne
xt']")).click();
error log
error log
Exception in thread "main" java.lang.NoSuchMethodError: com.google.common.base.Preconditions.checkState(ZLjava/lang/String;Ljava/lang/Object;)V
at org.openqa.selenium.remote.service.DriverService.checkExecutable(DriverService.java:136)
at org.openqa.selenium.firefox.GeckoDriverService.access$000(GeckoDriverService.java:41)
at org.openqa.selenium.firefox.GeckoDriverService$Builder.usingFirefoxBinary(GeckoDriverService.java:108)
at org.openqa.selenium.firefox.FirefoxDriver.toExecutor(FirefoxDriver.java:204)
at org.openqa.selenium.firefox.FirefoxDriver.(FirefoxDriver.java:108)
at org.openqa.selenium.firefox.FirefoxDriver.(FirefoxDriver.java:104)
at register_prctc.gmail.main(gmail.java:15)
Here is the solution to your Question:
To work with Selenium 3.4.0, geckodriver v0.16.1 & latest Mozilla Firefox 53.x you need to set the absolute path of the geckodriver in your code as:
System.setProperty("webdriver.gecko.driver","C:\\your_dir\\geckodriver.exe");
As per best practices you should not use Thread.sleep(6000), instead use ImplicitlyWait or ExplicitWait.
The xpath .//[#id='gbw']/div/div/div[1]/div[1]/a you used doesn't identifies any unique element. To find the element Gmail link you can use the linkText locator as:
wd.findElement(By.linkText("Gmail")).click();
For sending text into Email or Phone field provide a unique xpath as:
WebElement e1= wd.findElement(By.xpath("//input[#id='identifierId']"));
The xpath to click on Next button looks vulnerable to me, you may like to change it to : wd.findElement(By.xpath("//div[#id='identifierNext']/content/span[text()='Next']")).click();
Here is the working set of your own code with some simple tweaks:
System.setProperty("webdriver.gecko.driver","C:\\geckodriver.exe");
WebDriver wd= new FirefoxDriver();
wd.get("https://www.google.co.in/");
wd.findElement(By.linkText("Gmail")).click();
WebElement e1= wd.findElement(By.xpath("//input[#id='identifierId']"));
e1.sendKeys("id#gmail.com");
wd.findElement(By.xpath("//div[#id='identifierNext']/content/span[text()='Next']")).click();
Let me know if this Answers your Question.
Remove Selenium-java-2.53.1.jar file and update all jars