i'm trying to find a web element in a web page coded with Polymer,
the source is:
<iron-ally-announcer>==0
<div class="style-scope iron-ally-announcer" aria-live="polite">Invalid credentials</div>
</iron-ally-announcer>
I can find with xpath but i want to find by classname or id
if i try =
driver.findElement(By.className("style-scope iron-ally-announcer"));
it cannot find.
The element is an alert message.
By.className receives one class as parameter, style-scope and iron-ally-announcer are actually two classes in that WebElement. It should be
driver.findElement(By.className("style-scope"));
// or
driver.findElement(By.className("iron-ally-announcer"));
If you want to use both of them you can do it with cssSelector
driver.findElement(By.cssSelector(".style-scope.iron-ally-announcer"));
Related
Showcase of issue
Unable to click on this dropdown list since it does not have an ID, how could I click on this select class?
You can use the classname, classname with the element name to locating the element.
await t.click(Selector("select.product_sort_container"));
You will have to master location strategies to locate elements in the web pages. All elements will not have IDs.
Reference :
Select Page Elements
Mastering CSS for web automation
Recipe : Test <Select> Elements
Refer to this documentation to learn how to use selectors to select elements.
Since your dropdown has an html attribute you can use Selector.withAttribute Method.
Hi I am looking for an explanation on how selenium searches for an element on a website. For us, we use inspect element to find the id, name, xpath, etc. of an element, and then put it in selenium for some action to be done. How does selenium find the element we tell it to find? Does it ctrl shift J like us and inspect element?
Note: I am not looking for how to code selenium to find element.
Html pages are just documents with elements structured like in a tree.
In general
Selenium uses element locators to find things. Locators work lazily. When you look up an element Selenium first checks if its cached. If not, it uses SearchContext which finds all elements within the current context (eg. DOM element) using a given mechanism, for example by XPathEvaluator.
SearchContext runs findElement() if you are looking for one element or findElements() if you are looking for more than one.
In simple terms, findElement() tries to run JavaScript script to find the element asynchronously. If it can’t, it tries to find it directly by using an interestingly called method – xpathWizardry, i.e. by using XPathEvaluator evaluation.
XPath
When you use XPath (XML Path Language) in Selenium, this is just a way to navigate through hierarchical structure of an XML-like document, such as html.
XPath uses a non-XML syntax to provide a flexible way of pointing to different parts of an XML document.
Internally selenium uses W3 XPathEvaluator, which evaluates XPath expressions.
You can study XPathEvaluator source code here.
Search Context
The SearchContext is a topmost interface present in the Selenium WebDriver hierarchy. It has two methods that will be the abstract as SearchContext is an interface.
findElement(): Find the first WebElement using the given method.
WebElement findElement(By by)
Parameters:
by - The locating mechanism
Returns:
The first matching element on the current context
Throws:
NoSuchElementException - If no matching elements are found
findElements(): Find all elements within the current context using the given mechanism.
java.util.List<WebElement> findElements(By by)
Parameters:
by - The locating mechanism to use
Returns:
A list of all WebElements, or an empty list if nothing matches
The browser DOM exposes API like querySelector,querySelectorAll, getElementById, getElementsByClassName, getElementsByName, etc through javascript that can be used to locate elements.
For example :
Navigate to www.bing.com
Press F12 to open developer console.
Enter document.querySelector("#sb_form_q") to locate search box input by css selector. I am using #Id here as css selector.
Enter document.getElementById("sb_form_q") to locate search box input by it's Id
Enter document.getElementsByClassName("sb_form_q")[0] to locate search box input by it's class name
Enter document.getElementsByName("q")[0] to locate search box input by it's name
All of above should return "<input id="sb_form_q" class="sb_form_q" name="q" type="search" maxlength="1000" autocomplete="off" aria-label="Enter your search term" autofocus="" aria-controls="sw_as" aria-autocomplete="both" aria-owns="sw_as" aria-activedescendant="sa_5004">" same result.
Selenium uses these DOM API to retrieve the elements. However, selenium might use these DOM API via some other mechanism (e.g C ++) and not by executing javascript for faster execution. XPath lookup is something not supported directly by browser DOM API. Selenium probably provides it's own implementation for XPath lookup or rely on some browser polyfill for this functionality.
I am trying to automate Salesforce application Using Selenium and getting NoSuchelementException though XPATH is correct and valid for particular object. When i have searched the issue, it might be reason for Shadow DOM.
For EX:
So XAPTH i have written like,
driver.findElement(By.xpath("//input[#name='Name']")).sendKeys("Jams");
or
driver.findElement(By.xpath("//input[#id='input-299']")).sendKeys("Jams");
This XPATH is highlighting in Console as well. But while automating it throws nosuchelement error.
So while checking for ShadowDOM option, am getting option like this for Name Object.
#shadow-root(user-agent)
Shadowroot DIV
-- nothing mentioned in div. it just open and closed tags.
How to automate this?
You can check if there are any iframes in your Dom. Simply do //iframe in your page developer mode(F12)> elements tab > search (Ctrf+F) area. If there are any, you will get the number of iframes.
Now if your textbox is in any of iframe use below code to go inside particular iframe first
driver.switch_to.frame("<name or Id of frame>")
then come out to frame use below:
driver.switch_to.parent_frame()
Also, if the issue is not related to frames check below for shadow-root related issue:
you can check below for shadow-root element ( Question is for Java, but you can co-relate):
How to interact with the elements within #shadow-root (open) while Clearing Browsing Data of Chrome Browser using cssSelector
The website contents are mostly created now using javascript. You may have to wait for certain elements to load before doing anything to it.
https://seleniumbyexamples.github.io/wait
I am trying to get the xpath of a 'Form' element by its id that is inside an iframe.
In chrome xpath plugin when i query
//iframe[contains(#id,'fraModalPopup')]
it gets me the iframe but when i try to get anything down the hierarchy it just returns null. e.g. if i try doing
//iframe[contains(#id,'fraModalPopup')]/html // returns null
or
//iframe[contains(#id,'fraModalPopup')]/form[contains(#id='aspnetForm')]
// not sure if it is a right xpath statement - also returns null
would please anyone guide me how I can get hold on to the form element? I have to use this xpath inside RIDE (Robot Framework).
iframe is an element inside main HTML DOM that contains its own embedded HTML DOM. You don't need to use iframe as context node to find form inside frame, but you need to switch to that iframe
select frame id=fraModalPopup
to be able to handle elements inside embedded HTML DOM (no need to add "//iframe" to XPath)
xpath=//form[#id='aspnetForm']
The documentation on code.google.com describes the elementIdElement functionality as "Search for an element on the page, starting from the identified element". Does this mean the search is done for every element following that element throughout the rest of the web page or only for dependents of that element?
If it is the former, then how would I construct the "value" entry if the "using" parameter is "css selector" and I want to find a descendant of the current element's sibling? I thought the value would be "+ div .classname", but this doesn't seem to work.
One way you can do it is by emulating Selenium ByChained, by calling one wait after another:
browser
.useXpath()
.url('http://www.google.com')
.waitForElementVisible('.//body', 1000)
.waitForElementVisible(".//div[contains(#class, 'classVar')]")
.click('button')
The correct xpath string for navigating to an element's parent's following sibling for the existence of another element with a given class is
'(//div[#id="currentElementID"]/../following-sibling::*[1]//div[contains(#class,"classToLookFor")])[1]'
In this example, I know the current element's ID so that's what I use, but the '//div[#id="currentElementID"]' can be replaced with whatever you need to navigate to the starting element. Also, this example assumes the element I'm looking for is a div.