VBA click button with no ID - vba

How can I click without class name, the link with the following element is as follows:
Add Range +
The complete element before and after it is as follows:
<li class="rangeDefault">
Add Range +
</li>
This is the vba code i used but did not work:
doc.getElementsByTagName("Add Range +").Click

Try using the querySelector Method of the HTMLDocument object, which will allow you to get the desired element by the onclick attribute...
doc.querySelector("[onclick='ChooseRange()']").click

Related

Selenium VBA Unable to Click Checkbox

Using Selenium and Chrome, I'm attempting to check a box located within a table. The table contains 2 checkboxes but they act as radio buttons, in that if I click one, the other will uncheck.
I've tried a variety of methods, which include the following:
Const CHECKED_STATE As String = "Ag-icon ag-icon-checkbox-checked"
findElementByClassName("ag-selection-checkbox").fireEvent("CHECKED_STATE")
findElementbyXPath("//span[#class=ag-icon ag-icon-checkbox-checked'])[1]").Click
findElementbyXPath(".//div[#class='ag-body-container']").Click
I'm not sure how to click the checkbox when the HTML code doesn't even have a checkbox type or an Id.
The HTML reads:
<span class="ag-icon-checkbox">
<span class = "ag-icon ag-icon checkbox-checked ag-hidden">
<span class = "ag-icon ag-icon checkbox-unchecked">
<span class = "ag-icon ag-icon checkbox-undeterminate ag-hidden"></span>
When I click on the checkbox, the unchecked and hidden lines of HTML will flip. So I'm guessing it's some sort of event that I have to trigger.
The following, depending on the rest of the html, should work to select the unchecked item and thereby toggle off the other item. It targets the class checkbox-unchecked:
driver.FindElementByCss(".ag-icon-checkbox .checkbox-unchecked").click

“Click” a javascript button with VBA

I am trying to use VBA to click the button: search job posting
button
The html code:
<td><br> <input type="submit" class="btn btn-primary btn-small" value="Search"></td>
<td><br>-or - Search Job Postings
I was attempting to do it by something like:
IE.document.Something.Click
Much appreciation for someone who can help me to figure out the "something"!!!
There are probably better ways to identify a button, but when I was testing this stuff for fun a long time ago checking the onclick property was the only reliable way to identify a button on the site I was interfacing with. I'm assuming you know how to reference the browser window based off what you said. I included the Microsoft HTML Object Library to get the HTMLButtonElement type.
Dim htmlElements as Variant
Dim buttonElem As HTMLButtonElement
Set htmlElements = IE.Document.getElementsByTagName("BUTTON")
For Each buttonElem In htmlElements
If InStr(1, buttonElem.onclick, "orbisApp.buildForm({action:'displayAdvancedSearch'}).submit()") > 0 Then
buttonElem.Click
End If
Next
All you need to do is simply use the form element to click the button. Your statement:
IE.document.Something.Click
Is almost spot on.
Here's the code you want to use
IE.document.Forms(0).Submit

Is there a possibility to address elements on a website which have no ID?

In Vb.net, with a Webbrowser, I normally use GetElementByIdto address for example a button. I know that there is GetElementFromPoint, which I find extremly laborious.
Is there a better, simpler way when the ID is unknown?
You will need to use some type of selector.
The GetElementByID method works best because if the HTML file is formatted correctly then there should only be one element with that unique ID.
The GetElementFromPoint will return an element based on the X,Y coordinate of the document, this is best used in the Document's Click event.
The GetElementByTagName name will return a collection of elements and works if you know the tag type of the element, such as <button>...</button> or <p>...</p>. To help narrow down which element you want, you will need to then iterate through the returned collection and compare either the element's attributes if you know their respective values or the element's text via the InnerHTML property.
The last and least effective method is the All property which returns every element in the document. The reason why this is the least effective is because at least with GetElementByTagName, you can narrow down the collection based on the tag's name.
However, let's assume that you have the following markup:
<body>
<p>Look at my super complex HTML markup.</p>
<button>Click Me</button>
<button>No, click me!</button>
</body>
You could then get the button tag that says "Click Me" by using the following:
Dim click_me As HtmlElement = WebBrowser1.Document.GetElementByTagName("button").SingleOrDefault(Function(e) e.InnerHtml = "Click Me")
Seeing as this question is asked every now and then I'll see if I can't try to tackle this once and for all. Here's a more extensive guide on how to find elements that don't have an ID:
- The basics -
There are plenty of built-in properties and methods you can use in order to identify an element. The most common ones include:
HtmlElement.GetElementsByTagName()
Method. Returns a collection of all elements in the document/element having the specified HTML tag. This can be called both on a HtmlElement but also on the HtmlDocument itself.
HtmlElement.GetAttribute()
Method. Returns the value of a specific attribute on the specified HtmlElement.
HtmlElement.InnerHtml
Property. Returns all HTML code located inside the specified element (but not the code for the element itself).
HtmlElement.InnerText
Property. Returns all text (stripped from HTML code) located inside the specified element.
HtmlElement.OuterHtml
Property. Returns the HTML code located inside the specified element, including the code for the element itself.
These methods and properties can all be used in different ways to identify an element, as illustrated by the examples below.
NOTE: I omitted HtmlElement.OuterText because its behaviour is a bit odd, and I'm not 100% sure what it actually does.
- Examples of finding elements with no ID -
Following are a set of examples of how you can use the previously mentioned methods and properties in order to find the element you're looking for.
Finding an element by its class(-name)
To find and element based on its class attribute you have to iterate all elements and check GetAttribute("className") on each. If you know the element type (tag name) beforehand you can narrow the search by first getting a collection of all the elements of that type using HtmlDocument.GetElementsByTagName() instead of HtmlDocument.All.
HTML code:
<div class="header">
<div id="title" class="centerHelper">
<img id="logo" src="img/logo.png"/>
</div>
<p class="headerContent">
Hello World!
</p>
</div>
Element to locate:
<p class="headerContent">
VB.NET code:
'Iterate all elements.
For Each Element As HtmlElement In WebBrowser1.Document.All
If Element.GetAttribute("className") = "headerContent" Then
'Found. Do something with 'Element'...
Exit For 'Stop looping.
End If
Next
Finding an element based on an attribute, located inside another element (with ID)
In order to find a child element based on one of its attributes, where the child is located inside a parent element (that has an ID) you simply need to get the parent element by its ID and then iterate all its children.
HTML code:
<select id="items" class="itemsList">
<option value="2">Apple</option>
<option value="3">Orange</option>
<option value="5">Banana</option>
</select>
Element to locate:
<option value="5">Banana</option>
VB.NET code:
'Iterate all children of the element with ID "items".
For Each Element As HtmlElement In WebBrowser1.Document.GetElementByID("items").Children
If Element.getAttribute("value") = "5" Then
'Found. Do something with 'Element'...
Exit For 'Stop looping.
End If
Next
Finding an element based on an attribute, located inside another element (without ID)
To find a child element based on one of its attributes, where the child is located inside a parent element (that doesn't have an ID) you first have to create an outer loop that looks for the parent element. Then, when found, you can start iterating the children.
HTML code:
<select class="itemsList">
<option value="2">Apple</option>
<option value="3">Orange</option>
<option value="5">Banana</option>
</select>
Element to locate:
<option value="5">Banana</option>
VB.NET code:
'Variable keeping track of whether we found the element we're looking for or not.
Dim ElementFound As Boolean = False
'Outer loop, looking for the parent object (<select class="itemsList">).
For Each Element As HtmlElement In WebBrowser1.Document.GetElementsByTagName("select") 'Iterate all <select> tags. You can use Document.All here as well.
If Element.getAttribute("className") = "itemsList" Then
'Parent found.
'Inner loop, looking for the child element we want (<option value="5">Banana</option>).
For Each OptionElement As HtmlElement In Element.GetElementsByTagName("option")
If OptionElement.GetAttribute("value") = "5" Then
'Found. Do something with 'OptionElement'...
ElementFound = True
Exit For 'Exit the inner loop.
End If
Next
'Exit the outer loop if we found the element we're looking for.
If ElementFound Then Exit For
End If
Next
Finding an element based on its InnerText
In some cases the element you want to locate doesn't have any attributes or is simply too similar to a lot of other elements on the site. In this case, if its contents are always the same you can identify it via its InnerText or InnerHtml properties.
HTML code:
<h1>Important information</h1>
<p>Please read this information through <b>carefully</b> before continuing.</p>
<h2>Copyrighted material<h2>
<p>All material (text, images, video, etc.) on this site are <b>copyrighted</b> to COMPANY NAME.</p>
Element to locate:
<h2>Copyrighted material<h2>
VB.NET code:
For Each Element As HtmlElement In WebBrowser.Document.All
If Element.InnerText = "Copyrighted material" Then
'Found. Do something with 'Element'...
Exit For 'Stop looping.
End If
Next
Finding an element based on its InnerHtml
Finding an element based on its InnerHtml works exactly the same way as when you look based on its InnerText apart from that the string you're checking now also includes HTML code.
HTML code:
<h1>Important information</h1>
<p>Please read this information through <b>carefully</b> before continuing.</p>
<h2>Copyrighted material<h2>
<p>All material (text, images, video, etc.) on this site are <b>copyrighted</b> to COMPANY NAME.</p>
Element to locate:
<p>All material (text, images, video, etc.) on this site are <b>copyrighted</b> to COMPANY NAME.</p>
VB.NET code:
'Iterate all <p> tags.
For Each Element As HtmlElement In WebBrowser.Document.GetElementsByTagName("p")
If Element.InnerHtml.Contains("<b>copyrighted</b>") Then
'Found. Do something with 'Element'...
Exit For 'Stop looping.
End If
Next

Simulate Click event on a DIV element

I cannot simulate a click event on a div element. The HTML code is this one:
<div id="export" data-export="true" data-timespan="">
<button class="btn btn-default ladda-button" type="button" data-style="expand-right" data-spinner-color="#8899a6">
<span class="Icon Icon--featherDownload"></span>
<span class="ladda-label">
Exportar datos
</span>
<span class="ladda-spinner"></span></button>
<div class="hidden error server Callout Callout--danger">
<p>Ocurrió un problema al exportar tus datos, inténtalo de nuevo más tarde.</p>
</div>
</div>
In the webpage, is just a button that downloads a file when clicked. There is no URL. But after checking the code, is the div element what triggers the click event. Look the image.
Click to see image
That "g.handle" triggers a js.file form the website.
My vba code works perfect for doing other stuff in the website, but I cannot accomplish this task.
I've tried all this options:
Set div = HTMLDoc.getElementById("export")
div.FireEvent ("onclick")
div.Click
HTMLDoc.all.Item
Call HTMLDoc.parentWindow.execScript("g.handle", "JavaScript")
Nothing works. I'm kind of blocked right now and I have no idea of how to proceed. Maybe this has no solution? I have almost no idea of HTML and I have 0 idea of Javascript. But it must have a solution, because if I do it manually, i click on that DIV, wait some seconds and download my file.
Thanks in advance. Any help is welcome.
You didn't specify if the highlighted portion was the html code for the button or not, but it appears from looking at it that it isn't.
You can grab the class name for your button. The name may or may not be unique, and it's difficult to know that without seeing the entire html code, but you can set the btn variable below to the first instance of that class name. If there are multiple class names in your html code, then you will need to use a For Each...Next statement to iterate through them (unless you know the instance number off hand).
So we will go with the first instance of your class, hence the reason for the (0) appended on the end.
Sub Test()
Dim ie As New InternetExplorer, HTMLDoc As HTMLDocument, btn As Object
ie.navigate Url 'whatever this may be
' Some code to wait for your page to fully load
Set HTMLDoc = ie.document
Set btn = HTMLDoc.getElementsByClassName("btn btn-default ladda-button")(0)
btn.Click
End Sub

Issue selecting Radio button in Selenium Webdriver

<table id="Content_Content_Content_ctlCaseInfo_rdochldplcm" class="fltLeft">
<tr>
<td><input type="radio" id="Content_Content_Content_ctlCaseInfo_rdochldplcm_0" name="ctl00$ctl00$ctl00$Content$Content$Content$ctlCaseInfo$rdochldplcm" value="0" /><label for="Content_Content_Content_ctlCaseInfo_rdochldplcm_0">No</label></td><td><input type="radio" id="Content_Content_Content_ctlCaseInfo_rdochldplcm_1" name="ctl00$ctl00$ctl00$Content$Content$Content$ctlCaseInfo$rdochldplcm" value="1" /><label for="Content_Content_Content_ctlCaseInfo_rdochldplcm_1">Yes</label></td>
</tr>
</table>
When I try
driver.FindElement(By.Id("Content_Content_Content_ctlCaseInfo_rdochldplcm")).Click();
it clicks to "Yes"
When I try driver.FindElement(By.Id("Content_Content_Content_ctlCaseInfo_rdochldplcm_0")).Click();
OR
driver.FindElement(By.Id("Content_Content_Content_ctlCaseInfo_rdochldplcm_1")).Click();
Nothing happens and no radio button gets selected.
Please suggest ways to handle this situation ..thanks a lot!!
It would probably be better to click the Radio buttons through XPath.
In your specific case, the XPath for:
Yes - Radio Button:
"//input[contains(#id, 'rdochldplcm') and contains(#value, 1)]"
No - Radio Button:
"//input[contains(#id, 'rdochldplcm') and contains(#value, 0)]"
In this instance, if you wanted to click the 'Yes' Radio button, you can do this:
string yesRadioButtonXPath = "//input[contains(#id, 'rdochldplcm') and contains(#value, 1)]"
IWebElement yesRadioButton = driver.FindElement(By.XPath(yesRadioButtonXPath));
yesRadioButton.Click();
For the 'No' Radio button, you would use this:
string noRadioButtonXPath = "//input[contains(#id, 'rdochldplcm') and contains(#value, 0)]"
IWebElement noRadioButton = driver.FindElement(By.XPath(noRadioButtonXPath));
yesRadioButton.Click();
Since you're using a table, there may be a chance that the XPath may return more than one element. You'd need to use a different method to sort out the elements in that case, but for what you're looking for, this method should work.
this solved my problem perfeclty
I have a page with 18 radio buttons in 6 groups which represented "Yes" "No" and "No Answer"
I was trying to get them by ID but it was randomized by the app
But using a name and value tags made it work.
radios were defined basically like this:
input value="2" class=" x-form-radio x-form-field" autocomplete="off" id="randID_13578" name="emailNotifiyOptionAllow" type="radio">
and every time i opened this page id was different so using
"//input[contains(#name, 'emailNotifyOptionAllow') and contains(#value, 1)]"
solved it.
Thanx
Use this :
//First get the list of values from the radio button
List < WebElement > elements = driver.findElements(By.cssSelector("table[id='Content_Content_Content_ctlCaseInfo_rdochldplcm'] > td"));
WebElement value;
//use loop for searching the particular element
for(WebElement element : elements){
//Getting the value of the element
value = element.findElement(By.cssSelector("label")).getText();
//condition to click on the element
if(value.trim().equals("No")){ //Here value is hard coded. You can take from excel sheet also
// If condition satisfies, it will click on the element
element.findElement(By.cssSelector("input").click();
}
}
This can be used as a common function also.
try [0] and [1] instead of the underscore.
Try your code with the given below CSS :
Step 1:
By Provided HTML Piece we can derive the CSS of the Radio Button
css=#Content_Content_Content_ctlCaseInfo_rdochldplcm input
Step 2:
Click on the radio button using Web Driver Code
driver.findElement
(By.cssSelector("#Content_Content_Content_ctlCaseInfo_rdochldplcm input"))
.click();