Unable to locate SVG elements through xpath on Kendo UI chart - selenium-webdriver

I did try some of xpaths but seems no luck.
I want to click on country and then graph , Given below screenshot :
Website URL is : https://demos.telerik.com/kendo-ui/bar-charts/column
I tried xpaths :
//text(text()='India')
//g//text(text()='India')

Hi you can click India with the following Xpath //*[text()='India']
This is a really helpful resource
I usually open chrome inspector and then hit cntrl+F to open up an interactive way to test my xpaths:
You can target the svgs by using their strokes, but note these may change often. example: //*[#d='M54.5 164.5 L 70.5 164.5 70.5 236.5 54.5 236.5Z' and #stroke='#03a9f4']

The elements on chart are from SVG-namespace, so you cannot use common syntax to select those elements (you wouldn't be able to select element by its tag name, e.g. //svg or //path, etc)
You can try below to select text node with text "India":
//*[name()="text" and text()="India"]

As the desired elements are SVG Elements you need to consider the namespace and induce WebDriverWait for the desired element to be clickable and to click on the first bar within the graph you can use the following solution:
Code Block:
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
options = webdriver.ChromeOptions()
options.add_argument("start-maximized")
options.add_argument("disable-infobars")
options.add_argument("--disable-extensions")
driver = webdriver.Chrome(chrome_options=options, executable_path=r'C:\Utility\BrowserDrivers\chromedriver.exe')
driver.get("https://demos.telerik.com/kendo-ui/bar-charts/column")
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "//div[#id='chart']//*[name()='svg']//*[name()='g']//*[text()='India']//following::*[name()='path']"))).click()
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "//div[#id='chart']//*[name()='svg']//*[name()='g'][contains(#clip-path, 'url')]//*[name()='path']"))).click()
Browser Snapshot:

Related

Find element by inner element text using selenium

I want to click an element by the text of a span who is the child of the element. How do I do this?
<button type="button" class="alert-button ion-focusable ion-activatable sc-ion-alert-md" tabindex="0"><span class="alert-button-inner sc-ion-alert-md">OK</span><ion-ripple-effect class="sc-ion-alert-md md hydrated" role="presentation"></ion-ripple-effect></button>
This is what I have tried but it didn't work.
#FindBy(css = "button[span:contains('OK')]")
Selenium doesn't supports the :contains pseudo-class anymore as #jari.bakken in their comment confirms:
AFAICT, the :contains pseudo-class isn't in the CSS spec and is not supported by either Firefox or Chrome (even outside WebDriver).
Further #dawagner in their comment also mentions:
contains isn't a valid CSS3 selector; because of this several browsers don't natively support contains, so Selenium (and WebDriver) don't claim to support it._
Solution
However you can still use the other attributes to construct a CssSelector to identify the element as follows:
#FindBy(css = "button.alert-button.ion-focusable.ion-activatable.sc-ion-alert-md span.alert-button-inner.sc-ion-alert-md")
As an alternative you can also use either of the following Xpath based locator strategies:
#FindBy(xpath = "//button[#class='alert-button ion-focusable ion-activatable sc-ion-alert-md']//span[#class='alert-button-inner sc-ion-alert-md']")
Using the innerText:
#FindBy(xpath = "//button[#class='alert-button ion-focusable ion-activatable sc-ion-alert-md']//span[#class='alert-button-inner sc-ion-alert-md' and text()='OK']")
or even:
#FindBy(xpath = "//span[#class='alert-button-inner sc-ion-alert-md' and text()='OK']")
even possibly:
#FindBy(xpath = "//span[text()='OK']")
CSS Selectors with Selenium do not support locating elements by their text content. Only XPath supports that.
Try this XPath:
//button//span[text()='OK']
or
//button//span[contains(.,'OK')]
or
//button//span[contains(text(),'OK')]
So the element could be defined as following
#FindBy(xpath= "//button//span[text()='OK']")
Or
#FindBy(xpath= "//button//span[contains(.,'OK')]")

Having issue with selecting drop down in selenium webriver

I have a sample HTML source of the dropdown.
I have tried with all possibilities but I having
"Exception in thread "main"
org.openqa.selenium.ElementNotInteractableException: element not
interactable" error in selenium web driver.
Plz, give me a solution to select the dropdown values in the web driver. What should I use?[HTML source here][1]
WebElement clickclientdrpdown=driver.findElement(By.xpath("/html/body/div[5]/div[3]/div[1]/div/div[4]/div/form/div[1]/span/span[1]/span/span[1]"));
clickclientdrpdown.click();
WebElement selectclientdrpdown = driver.findElement(By.xpath("/html/body/div[5]/div[3]/div[1]/div/div[4]/div/form/div[1]/span/span[1]/span/span[1]"));
selectclientdrpdown.sendKeys("1 Private solution");
Your xpath is prone to breaking easily if the format of the HTML ever changes, just use findElement(By.Name), the name attribute is less likely to change as it is part of the Form and name is the parameter name passed to the server:
//Selenium method specific, prone to failure if element is disabled or not visible
WebElement selectclientdrpdown = driver.findElement(By.name("companyId"));
selectclientdrpdown.sendKeys("1 Private solution");
//Using the JavascriptExecutor
JavascriptExecutor js = (JavaScriptExecutor)driver;
js.ExecuteScript("document.querySelector("select[name='companyId'].value = '1 Private solution';");

Selenium says form textbox Element is read-only - but it is not

I had this working previously, but something changed and I wanted to move it to a different vm anyway. The page does not appear to have changed. fields are still L1 and P1. There are no popups or whatever.
The error I get is:
selenium.common.exceptions.InvalidElementStateException: Message: Element is read-only: <input id="L1" class="LoginFormData" name="L1" type="text">
Debian Stretch
Python 2.7.13
Selenium v3.141.0
Geckdriver v0.24.0
Code:
from pyvirtualdisplay import Display
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
display = Display(visible=0, size=(1024, 768))
display.start()
driver = webdriver.Firefox()
driver.get("https://testsite.org/")
username = driver.find_element_by_name("L1")
username.clear()
username.send_keys("test user")
password = driver.find_element_by_name("P1")
password.clear()
password.send_keys("logmein")
driver.find_element_by_id("login").click()
driver.get("https://testsite.org/Overview.aspx")
driver.save_screenshot('screenie.png')
driver.close()
display.stop()
This is the path and csspath:
//*[#id="L1"]
#L1
html body.BodyHome form#frm center table tbody tr td.PageBody div#divPageDetail.PageDetail table tbody tr td.Blank table tbody tr td.IntroLeft table tbody tr td.Blank div.IntroHeaderLogin table tbody tr td.LoginFormData input#L1.LoginFormData
Well, I was able to work around this by adding the following line. I would like to know if there is a better way. Thanks
driver.execute_script('document.getElementsByName("L1")[0].removeAttribute("readonly")')

How to find element in nested span using Selenium WebDriver?

I am trying to click on 'New Trade' link which is in span n6 which is a child element of span n2. I am able to reach till n2 but its not identifying 'n6'.
Please help I am new to Selenium WebDriver
Here I am posting the html and my code.
Trading
New
Trade
Trade
Explorer
I want to click on New Trade
HTML source code
My code which went till span 'n2':
driver.switchTo().frame(driver.findElement(By.name("treeFrame")));
WebElement allFormChildElements = driver.findElement(By.name("the_form"));
allFormChildElements.findElement(By.linkText("Trading")).click();
WebElement modalDialog = allFormChildElements.findElement(By.className("border"));
WebElement newmodalDialog = modalDialog.findElement(By.className("formScrollableMenuContent"));
System.out.println(newmodalDialog.findElements(By.tagName("a")).size()); // ans 5
WebElement newDialog= newmodalDialog.findElement(By.id("n2"));
System.out.println(newDialog.findElements(By.id("n3")).size()); // ans 0
With the image I can't test but, if you are able to reach the element <span id="n2">, from there you could use the following xpath in order to click the element with the text "New Trade":
newDialog.findElement(By.xpath(".//span[#id='n6']/a[#name='A6' and text()='New Trade']")).click();
EDIT
If the id value change, try in this way:
newDialog.findElement(By.xpath(".//span/a[#name='A6' and text()='New Trade']")).click();
Could you please try below xpath
//a[contains(text(),"New Trade")]

Purpose of findElement method in WebElement (Selenium)

I am learning Selenium WebDriver and I am facing some trouble.
I am unable to get the purpose of the methods findElement,findElements in WebElement when we already have them in WebDriver. What is the difference between the methods in WebElement and WebDriver?
WebDriver driver;
WebElement webObject;
driver.findElement() searches for the element/s on the entire web page while webObject.findElement() searches for the element/s within the webObject object.
Example:
webObject = driver.findElement('some webtable');
webObject.findElement('some cell') :: searches for the cell within that particular table.
driver.findElement('some cell') :: searches for the cell within the entire web page.
Say you have a
<div id="parent">
<a id="child">child</a>
</div>
You can do
WebElement div = driver.findElement(By.id("parent"));
WebElement a = div.findElement(By.id("child"));
so you're able to search inside the elements

Resources