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();
Related
I'm trying to click on a unordered list element for the element id = search_explorer, but can figure out how to find the drop down list item so I can click on it. Here is the elements and what I have tried. ele returns null. Can someone please help me?
<ul class="menu menu_header dropit">
<li class="dropit-trigger menu_tools_item dropit-open"> KEYWORD
<ul style="width: 175px;" class="dropit-submenu">
<li class="menu menu_header menu_header_item dropit menu_tools_item" id="keyword_explorer" domain="0"><a class="menu_tools_item_a" href="#">Keyword Explorer</a></li>
<li class="menu menu_header menu_header_item dropit menu_tools_item" id="search_explorer" domain="0"><a class="menu_tools_item_a" href="#">Search Explorer</a></li>
</ul>
</li>
</ul>
ele = driver.FindElements(By.CssSelector(".menu.menu_header.menu_header_item.dropit.menu_tools_item")).FirstOrDefault(x => x.Text == "Search Explorer");
ele.Click();
It seems you need to click on drop down element to open the list and click on the specific element. Use WebDriverWait() and wait for ElementToBeClickable()
new WebDriverWait(driver, TimeSpan.FromSeconds(10)).Until(SeleniumExtras.WaitHelpers.ExpectedConditions.ElementToBeClickable(By.CssSelector(".menu.menu_header.dropit")));
new WebDriverWait(driver, TimeSpan.FromSeconds(10)).Until(SeleniumExtras.WaitHelpers.ExpectedConditions.ElementToBeClickable(By.CssSelector("#search_explorer >a")));
----Update---
Based on the updated information from the comments:
var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
// Use Actions to simulate mouse movement
Actions action = new Actions(driver);
// Move to the first element to hover
action.MoveToElement(driver.FindElement(By.CssSelector(".dropit-trigger")));
// Wait for search_explorer element to be visible
wait.Until(ExpectedConditions.ElementToBeClickable(By.Id("search_explorer")));
// Assign the search_explorer element to a variable
var searchExplorer = driver.FindElement(By.Id("search_explorer"));
// Move to the search_explorer element now that it's visible
action.MoveToElement(searchExplorer);
// call Actions.Perform() to execute the actions in the browser
action.Perform();
// Now click search_explorer element
searchExplorer.Click();
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))
i am trying to get this button with selenium in c#
<a id="1|0AqnCSdkjQ0|none" href="" target="_self" rel="nofollow" class="download_link 1">Download</a>
i tried with id and class but it didn't work.
Here is the web page:
http://www.mp3juices.cc/ - > on the next page
Your code is failing with that "Compound class" error because you are, basically, asking for two class names.
The button has the class download_link.
If you do something like driver.findElements(By.className("download_link")) you'll get a List of all the buttons, and get whichever you wanted.
(The above snippet is Java, so you may have to adapt it to C#)
you can use this as a solution
driver.findElement(By.xpath("//a[#class='download_link 1'] and contains(text(),'Download')"));
Did you try
driver.FindElement(By.CssSelector("a.download_link.2")
When you tried to use "download_link 2" you were requesting two class names. You can specify two class names (or more) in a CSS Selector and put a period between them. The CSS selector above is read as find an A tag with class download_link and class 2.
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
try
{
IWebElement myDynamicElement = wait.Until<IWebElement>((d) =>
{
try
{
return d.FindElement(By.ClassName("dl_link 1"));
}
catch
{
return null;
}
});
}
catch(Exception e)
{
}
ReadOnlyCollection<IWebElement> lists = driver.FindElements(By.ClassName("download_link"));
lists[0].Click();
*The code is not optimized, but it works great. (First part i am using to wait for the button to be loaded).
Im trying to select an item from lookup list, its not like drop down list. If you write something that matches the contents of the lookup list, all the matching contents show up in the list and you cannot simply type in the text field even if you know the item from lookup list, you HAVE to click on the item from lookup list in order for it to populate in the text field.
What Im doing is, Im writing the complete text of a valid field value in the field so that it is the only item that appears in the lookup list and then trying to search that list item so that it can be clicked, but whatever i try, the item isnt found. here is what I have tried already:
here is the html:
<body>
<div class="body-home"></div>
<script type="text/javascript"></script>
<script></script>
<div id="cboxOverlay" style="display: none;"></div>
<div id="colorbox" class="" style="display: none;"></div>
<ul id="ui-id-1" class="ui-autocomplete ui-menu ui-widget ui-widget-content ui-corner-all" tabindex="0" style="z-index: 1; display: none; top: 456.783px; left: 468.033px; width: 247px;">
<li class="ui-menu-item" role="presentation">
<a id="ui-id-27" class="ui-corner-all" tabindex="-1">
<span style="padding:10px;"></span>
</a>
</li>
The last tag in above html is the one Im trying to get.
here is the xpath that i tried, ive tried the cssSelecter as well, nothing works.
IWebElement selectItem = driverX.FindElement(By.XPath("/ul[#id='ui-id-1']/li[1]/a"));
selectItem.Click();
Any help is highly appreciated.
Sophia
In order to type/select and item from lookup list, you should initially click the parent that contains the ul/li items. When you click the parent of it, the style associated with the ul/li (display: none) will be removed, so that you can interact with the ul/li.
From the HTML posted, we can observe that UL has a style with attributed display: none, this means we can't interact with it or with its children. If you post the complete HTML/the website url, may we can find the solution.
For example, check this website, which has similar kind of lookup list and below is the solution.
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium;
namespace TestSelenium
{
[TestClass]
public class UnitTest1
{
public ChromeDriver browser;
[TestMethod]
public void TestMethod1()
{
try
{
browser = new ChromeDriver();
browser.Navigate().GoToUrl("https://roofandfloor.com/");
System.Threading.Thread.Sleep(5000);
// Select City.
IWebElement parentDiv = browser.FindElement(By.ClassName("city-dropdown-search"));
parentDiv.Click();
this.SelectItem("Bangalore");
// Select Property.
parentDiv = browser.FindElement(By.ClassName("property-type-checkboxes"));
parentDiv.Click();
this.SelectItem("Villa");
// Select Bed room. Need to write separate code for this.
parentDiv = browser.FindElement(By.ClassName("bedroom-select-container"));
parentDiv.Click();
System.Threading.Thread.Sleep(1500);
IWebElement items = browser.FindElement(By.ClassName("search-bedrooms"));
foreach (IWebElement item in items.FindElements(By.TagName("span")))
{
if (item.Text.Contains("1 BHK"))
{
item.Click();
break;
}
}
// Select Max budget.
parentDiv = browser.FindElement(By.Id("s2id_priceMax"));
parentDiv.Click();
this.SelectItem("5 Lakhs");
// Select Build up area.
parentDiv = browser.FindElement(By.Id("s2id_areaMin"));
parentDiv.Click();
this.SelectItem("600 Sq.ft.");
// Select Possession.
parentDiv = browser.FindElement(By.Id("s2id_possessionDate"));
parentDiv.Click();
this.SelectItem("Ready to Occupy");
}
catch
{ }
}
private void SelectItem(string itemText)
{
System.Threading.Thread.Sleep(1500);
IWebElement items = browser.FindElement(By.Id("select2-drop"));
foreach (IWebElement item in items.FindElements(By.TagName("li")))
{
if (item.Text.Contains(itemText))
{
item.Click();
break;
}
}
}
}
}
Try to observe the HTML of the posted portal. The above solution works fine to select the lookup items.
Sophia,
Maybe you should try the most literal test 1st, i.e. by a known Id to see that it works:
IWebElement selectItem = driverX.FindElement(By.Id("ui-id-27"));
selectItem.Click();
Once you've established this, then you can really look closely at the generic structure (obviously using ui-id-27 is for this test only). I would then move onto looking at the XPath structure in the real case and establish a test between the presented Id and the generic Xpath element.
I'm using the following to click an element on a web page:
driver.FindElement(By.Name("SearchIcon")).Click();
HTML:
<span class="ticon ti-search ti-1x" name="SearchIcon"> </span>
It's suppose to be very easy and strait forward but I'm getting:
"{"errorMessage":"Element is not currently visible and may not be manipulated","request":{"headers":{"Accept":"application/json, image/png","Connection":"Close","Content-Length":"0","Content-Type":"application/json;charset=utf-8","Host":"localhost:54912"},"httpVersion":"1.1","method":"POST","post":"","url":"/click","urlParsed":
Putting a
NUnit.Framework.Assert.IsTrue(driver.FindElement(By.Name("SearchIcon")).Enabled);
before the click statement passes so apparently the element is there and visible once the test runs so I don't get what's wrong here.
I know this is a bit old but I stumbled across it. It may help others.
You could create an extension method that checks if an element exists:
public static bool Exists(this IWebElement element)
{
try
{
var text = element.Text;
}
catch (NoSuchElementException)
{
return false;
}
return true;
}
You could then Assert like:
var searchIcon = driver.FindElement(By.Name("SearchIcon"));
NUnit.Framework.Assert.IsTrue(searchIcon.Exists());