I'm trying to programmatically click a series of buttons on an HTML web page which looks as follows:
<div class="srp-actions blue-button"><a class="primary-action-button label" href="/people/invite?from=profile&key=243930744&firstName=Will&lastName=Yang&authToken=p8Oz&authType=OUT_OF_NETWORK&connectionParam=member_desktop_search_people-vertical-module&csrfToken=ajax%3A7824954558998584370&trk=vsrp_people_res_pri_act&trkInfo=VSRPsearchId%3A12487701484818103943%2CVSRPtargetId%3A243930744%2CVSRPcmpt%3Aprimary" data-li-result-interaction="instant-connect" data-li-success-text="Invite Sent" data-li-connect-href="/people/contacts-search-invite-submit?memIds=243930744&authTokens=p8Oz&authTypes=OUT_OF_NETWORK&from=voltron&firstName=Will&lastName=Yang&isAjax=true&connectionParam=member_desktop_search_people-vertical-module&csrfToken=ajax%3A7824954558998584370&trk=vsrp_people_res_invite_act&trkInfo=VSRPsearchId%3A12487701484818103943%2CVSRPtargetId%3A243930744%2CVSRPcmpt%3Aprimary">Connect</a><div class="secondary-actions-trigger"><button role="button" class="trigger"><span>Secondary Actions</span></button><ul class="menu"><li>Send InMail</li><li>Share</li></ul></div></div>
Here's the current code to find the button element and perform the action:
HtmlElementCollection elements = webBrowser1.Document.GetElementsByTagName("a");
// First find and click "Connect" buttons
foreach (HtmlElement item in elements)
{
if (item.OuterHtml.Contains("action-button label") &&
!item.OuterHtml.Contains("Message") &&
item.OuterHtml.Contains("OUT_OF_NETWORK"))
{
item.SetAttribute("href", item.GetAttribute("data-li-connect-href"));
item.InvokeMember("Click");
}
}
The code properly find the anchor element, but the InvokeMember method doesn't seem to yield any result, any idea what is wrong?
The tag you are using does not specify exactly which specific tag you need:
x = webBrowser1.Document.GetElementsByTagName("a")
Instead try :
x= webBrowser1.Document.GetElementsById("anchor_id");
x.InvokeMember("click");
Or try using following method to verify whether its the intended tag you're using via attribute.
if (element.GetAttribute(attribute).Equals(attName))
Related
I am not using selenium nor anything else, i just want to do it on the webbrowser on the windows form application.
I have a windows form application and i want to click on a button with code but there is no ID.
I tried using a lot of different things found on this websites forums, but none of this works.
Have you tried using WebBrowser.GetElementByTagName("div") and then checking each element against attribute type=submit?
Your code should look something like
HtmlElement submit = FindSubmitElement(webBrowser1.Document);
submit?.InvokeMember("submit");
public HtmlElement FindSubmitElement(HtmlDocument document)
{
HtmlElementCollection elems = document.GetElementsByTagName("div"); // since your tag is div
// this will return collection, even in case there is just one div, find the first one, having an attribute 'type' with value 'submit'
foreach (HtmlElement elem in elems)
{
string type = elem.GetAttribute("type");
if (!string.IsNullOrEmpty(type) && type == "submit")
{
return elem; // if div tag with attribute type is found exit and return that html element
}
}
return null; // if no div tags found with an attribute 'type' return null
}
Check more on GetElementsByTagName method on the MSDN docs. Code is taken from there and adjusted to your need.
Having issues with the MoveToElement function in Selenium Webdriver for C#. The MoveToElement doesn't seem to do anything.
I have the following HTML:
<div id="rounded-navigation-with-icons">
<ul>
<li class="navigation-item">
<ul>
<li>
</li>
</ul>
</li>
</ul>
</div>
The inner-most list is hidden initially, until the navigation-item is hovered over by the mouse.
I then have the following code to click the navigation-item-title, which is visible to Selenium, and then click the MembersTestPage link.
public bool SearchForElement(string elementToFind, Page.FindBy by)
{
var navigation = Page.FindElement("rounded-navigation-with-icons", Page.FindBy.ID);
if (navigation != null)
{
foreach (var item in navigation.FindElements(By.ClassName("navigation-item")))
{
var titleElements = Page.FindElements("navigation-item-title", Page.FindBy.ClassName);
Actions action = new Actions(Driver.Instance);
foreach (var moveToItem in titleElements)
{
try
{
// Move to the main navigation link container element, but it doesn't work
action.MoveToElement(moveToItem);
// Move the mouse position manually to the link's location
action.MoveByOffset(moveToItem.Location.X, moveToItem.Location.Y);
// This does correctly find the element
var element = Page.FindElement("a[href='MembersTestPage']", Page.FindBy.CssSelector);
action.MoveToElement(element);
// Click returns that the element is hidden/invisible and therefore cannot be clicked
element.Click();
return true;
}
catch (Exception)
{
}
}
}
}
return false;
}
You can see I have used MoveToElement by passing the element, and also by manually passing the X and Y values of the item, but neither are working.
If I find the elements by XPath, this works as expected.
What am I doing wrong? Thanks
When using Actions in Selenium, then you have to finally call the Perform() method, bc otherwise the actions are only collected internally but never executed in the browser.
You can either call
action.Perform();
or
action.Build().Perform();
It doesn't matter. If you omit the Build(), then Perform() implicitly calls it.
I had similar problem recently and my solution was to perform everything as one action:
action.MoveToElement(moveToItem)
.MoveByOffset(moveToItem.Location.X, moveToItem.Location.Y)
.MoveToElement(Page.FindElement("a[href='MembersTestPage']", Page.FindBy.CssSelector))
.click(Page.FindElement("a[href='MembersTestPage']", Page.FindBy.CssSelector))
.build()
.perform();
I have Menu Group:
<div class="menuGroup">
Some of this div contain class which hide or show menu contents
class="toggleMenuChildren">
When you click on it, it change on
class="toggleMenuChildren opened">
So I want show all content from menu (click on all classes toggleMenuChildren) to show it.
I try this
IWebElement zi = driver.FindElement(By.ClassName("toggleMenuChildren"));
zi.Click();
But this opened (unhide) just first element, and if you call it again then hide content. How I can show all content (click on all elements) ?
You can use xpath - //div[contains(#class,'toggleMenuChildren') and not(contains(#class,'opened'))]
(sorry it is in java)
List<WebElement> allElements = driver.findElements(By.xpath("//div[contains(#class,'toggleMenuChildren') and not(contains(#class,'opened'))]"));
for(WebElement ele: allElements){
ele.click;
}
You can try to use hover to show all the information under toggleMenuChildren class
Actions actions = new Actions(driver);
IWebElement menuHoverLink =
driver.FindElement(By.XPath("//div[#class='toggleMenuChildren']"));
actions.MoveToElement(menuHoverLink);
actions.Build().Perform();
//That is the elements under the toggleMenuChildren class that you can use
driver.FindElement(By.PartialLinkText("...")).Click();
after perform() line all the elements will be unhided .
I'm trying to open a web page in my webbrowser control and change the value of input fields. Works good when I'm doing it like this webBrowser.Document.GetElementById("Email").SetAttribute("value", "example#example.com");
on a page with defined element Ids, but now I've encountered a page where the html/javascript looks something like this:
<input id="${Id}" name="${Id}" type="text" class="text field" value="${Value}" title="${ToolTip}" />
So my question is how do I find this specific input field from the C# code?
Try This
This is a C# coding
HtmlElement Elem = AutomationWebBrowser.Document.GetElementById('<your element ID>');
Elem.SetAttribute("value", '<value to assign in input control>');
Also you can use variables inside the GetElementById and SetAttribute function
You can find element by class name by using the following function,
public static HtmlElement GetHTMLElementByClass(HtmlDocument document, String className)
{
foreach (HtmlElement element in document.All)
{
if (element.GetAttribute("className") == className)
{
return element;
}
}
}
I need to click the button "Add" in the post new wordpress form, this button is to add tags to the post , the trouble is that button don't have the value and id propertie. Is just like that
the html for the button
input type="button" class="button tagadd" value="Add" tabindex="3"
my tries
webBrowser1.Document.GetElementById("button tagadd").InvokeMember("click");
webBrowser1.Document.GetElementById("Add").InvokeMember("click");
"GetElementById without id"
:-)
Unless you can change the markup for the button
What you need now is to traverse the entire DOM and look for a button in a known place. I'd suggest adding jquery if not already exist to be able for easier dom manipulation/search.
If you add jquery you could do something like $(".tagadd").click()
You could try doing
webBrowser1.document.getElementsByClassName("tagadd")
EDIT: Here is a script to create the getElementsByClassName function if it's not available http://robertnyman.com/2008/05/27/the-ultimate-getelementsbyclassname-anno-2008/
There is also this http://msdn.microsoft.com/en-us/library/system.windows.forms.htmldocument.getelementsbytagname.aspx but I've never used it.
Add an ID. Even if you're dynamically generating the buttons this should be trivial.
If you're using jQuery,
$('.tagadd')
will return a collection of everything with the tagadd class applied. You can further filter this by the other classes (button, etc)
Use this:
onload=function(){
if (document.getElementsByClassName == undefined) {
document.getElementsByClassName = function(className)
{
var hasClassName = new RegExp("(?:^|\s)" + className + "(?:$|\s)");
var allElements = document.getElementsByTagName("*");
var results = [];
var element;
for (var i = 0; (element = allElements[i]) != null; i++) {
var elementClass = element.className;
if (elementClass
&& elementClass.indexOf(className) != -1
&& hasClassName.test(elementClass))
results.push(element);
}
return results;
}
}
}
and another
Some browsers provide the method getElementsByClassName() which lets you select by class without using jQuery (which is a bit heavy if this is all you need). I haven't tested this so I'm not sure how widely it's supported.
Did I mention that you should give everything an ID?
use TagName isteed for example
var elems = webBrowser1.Document.GetElementsByTagName("input");
foreach (HtmlElement elem in elems)
{
if (elem.GetAttribute("class") == "button tagadd")
{
elem.InvokeMember("click");
}
}