How to click on checkbox on webpage using selenium vba - vba

I have a query,how to click on checkbox on webpage using selenium vba.
Below is the screen shot where i want to click
Below is the html code.
<span name="locSpans[]" value="Nerul" style="display:block">
<input type="checkbox" name="locArr[]" value="8897" onclick="enableDisableLocality(); showSelectedLoc();">Nerul
<br>
<input type="hidden" name="locArrVal[]" disabled="disabled" value="Nerul">
</span>

FindElementByCss is generally faster unless using IE, and then it depends which version of IE and what type of traversal is required.
Repeated tests have proven FindElementByCss to be more performant than FindElementByXPath (Note: that if there is a unique id present then selecting by id is always the first choice!)
In benchmarked tests Chrome and FireFox saw faster matching using CSS consistently across different traversal paths. They are optimized with CSS in mind and using CSS selectors is advocated as selenium best practice. IE was more variable with most instances of XPath being slightly more performant, but there being some clear paths that favoured CSS selection. Long XPath selectors will be costly and prone to breakage. Later versions of IE saw more variability. Opera12 browser came in with mixed results.
I would use a CSS selector:
So, for a simple selection based on likely unique attribute, I would go with an attribute CSS selector of [value='8897'] to target the value attribute. The [] means attribute selector. So value attribute with value of 8897.
driver.FindElementByCss("[value='8897']").Click
If you want to be more selective you can throw in an additional attribute selector, as follows, to target the type attribute.
driver.FindElementByCss("[type=checkbox][value='8897']").Click
When should I use XPath then?
Older IE versions for sure.
Any requirement for walking up the DOM would point to XPath usage.
XPath has some great additional locator strategies for hard to find elements, but that is not necessary AFAIK here. You can see some of the additional considerations here.

You can use xpath below to get checkbox, it means: find input with type="checkbox" and parent SPAN with text "Nerul".
driver.FindElementByXPath("//input[ancestor::span[normalize-space(.)='Nerul'] and #type='checkbox']").Click

Try this if not go for CSS Selector Option
bot.Window.Maximize
bot.FindElementByName("locArrVal").Click
bot.Wait 1000

Related

Why `nth-of-type` behaves differently in different browser versions?

Problem:
So I've run into a peculiar difference in behavior of :nth-of-type selector when applied to an element with tag type not being specified in selector.
Take the following HTML:
<div class="parent-class">
<header>...</header>
<div class="child-class">...</div>
<div class="child-class">...</div>
</div>
Now, this selector
.parent-class .child-class:nth-of-type(1)
should probably point to the first child div element, which it does in Chrome 59 and Firefox 54, but does not in Mink-drived Selenium browsers (Chrome 53 from selenium/hub:3.0.1-fermium and Firefox 50 from selenium/node-firefox-debug:2.53.0).
What nth-of-type does in those browsers is ignoring element types altogether - meaning, for selector to work one has to specify either:
.parent-class .child-class:nth-of-type(2)
or
.parent-class div.child-class:nth-of-type(1)
Question:
Why does the element type gets ignored in case of Selenium browsers?
Selenium is not known to have issues with :nth-of-type(). Perhaps it's a bug with Mink, since that behavior is clearly incorrect — :nth-of-type() should not require a type selector to work, as stated in my answer here.
It is a limitation of Symfony's CssSelector component which is used by Mink
Mink uses CssSelector to translate elements to xpath which is interpretable by the driver.
And this tool simply does not fully support several types of CSS selectors, which is actually stated in the official documentation:
Several pseudo-classes are not yet supported:
*:first-of-type, *:last-of-type, *:nth-of-type, *:nth-last-of-type, *:only-of-type. (These work with an element name (e.g. li:first-of-type) but not with *.

selenium + capybara: find selector anywhere within element

Assume we have a <div class='whatever'> and somewhere deep inside there is an element <div class='inside-whatever'>
What i need is a way to access that particular inside-whatever-div using Capybara's and/or Selenium's methods.
Problem is, there is another <div class='inside-whatever'> on the page not inside <div class='whatever'>, so
within(:xpath,'//div[#class="whatever"]') do
find(:xpath,'//div[#class="inside-whatever"])
end
returns an error basically saying that there are multiple inside-whatever divs on the page.
What works is to build the xpath from whatever like
'//div[#class="whatever"]/div/div[3]/div/div[5]'
but that is pure madness.
So, is there any better way to look for selector anywhere inside any given element without having to specify a direct path?
You can merge your xpaths like this:
//div[#class="whatever"]//div[#class="inside-whatever"]
The real issue here is that you've fallen into the XPath // trap
find(:xpath,'//div[#class="inside-whatever"])
searches globally rather than from the context node. Instead you should get used to starting your XPaths with .// which will search from the current context node
within(:xpath,'.//div[#class="whatever"]') do
find(:xpath,'.//div[#class="inside-whatever"])
end
and do what you expect. This is mentioned in the Capybara README - https://github.com/teamcapybara/capybara#beware-the-xpath--trap
Note: CSS selectors don't have this issue and for most elements people are selecting read cleaner, which is why Capybara defaults to the :css selector
within('div.whatever') do
find('div.inside-whatever")
end

xpath is changing on each automation test run with Selenium

I have a major issue with Selenium which xpath is changing on each run. For instance, here is the field identifier for a postal code field on a warehouse module (one of the modules that we have in our system):
(.//*[#id='warehouseMaintenance:j_idt137_body']/table/tbody/tr[4]/td[4]))
it changes to
(.//*[#id='warehouseMaintenance:txtZip']))
during the execution.
any idea how to avoid this?
You should assign ID to the postal code field if possible.
Using chain to locate element is not a good practice.
If you have multiple pages and naming convention for each page are different. I suggest you to add a classname to the field, then using cssselector class$='postalcode' to locate the element.
For example,
<input type="text" class="xxx yyy warehouseMaintenance postalcode">
Did U tried using css's? They are not browser dependent.
U could use cssify to change your xpath's to css's or get it from browser.

Handling dynamic ids and classes

I am using selenium to test a web application, The ids and classes are always changing dynamically.So that I am not able to give correct identification, is it possible to get ids of the element in run time and is there any other method to handle this situation.
It depends on if ids are completely random or if there is some part of the id which remains the same. If yes, then cssSelector is the obvious choice
driver.findElement(By.cssSelector("div[id*=somePart]");
where id* means id contains. If you cant use this approach you will have to track down your element using xpath or again cssSelectors. XPath example is here and CSS selector could look like this
By.cssSelector("boyd table input");
I would strongly recommend locating elements by XPath -- with the caveat that you make your XPaths robust and not just "copy" the xpath using your browser's developer tools. XPath is very easy to learn. You can use XPaths to walk up and down the DOM, and identify elements by their text, or their attributes.
For example, maybe you need to click a button that has a span that contains the text that appears on the button:
<div class="btn-row random-generated-number-1234897395">
...
<button id="random-generated-number-239487340924257">
<span>Click Here!</span>
</button>
...
</div>
You could then use an xpath like this:
//div[contains(#class, 'btn-row')]//button/span[text()='Click Here!']/..
(The /.. at the end walks back up from the span to the button.)
XPath is powerful and flexible and easy to learn. Use it when the ids and classes aren't reliable.

Selenium object identification

I am using Selenium webdriver to test my application & i am facing difficulties in identifiying button on the same. the code snippet is like :
<input type="submit" onclick="return sign(this);" value="Login">
and its xpath is :
html/body/table/tbody/tr[2]/td/center/form/center/table/tbody/tr[3]/td/center/input[1]
Which object property to use and how?
You should not use that XPath.
I would hazard a guess that you used some sort of tool, whether it's Firebug or IDE, to generate that XPath. Stop that now!
XPath is fine to use, and can be used here, just not relying on the tools to generate it for you! That XPath is destined for failure!
You will need to provide more HTML, specifically around that button.
However, you should just be able to use something as simple as:
//input[#value='Login']
You can use the xpath, if that is really stable. I found that it is much easier to define id tags in the html elements and the use a By.id locator. Alternatively you can use css selectors, depending on the "uniqueness" of your button something like this could work:
By.cssSelector("input[value='Login']")