Selenium Webdriver: Selecting menu item in multi-level menu - c#

Selenium WebDriver in Visual Studio With C#.
I've create a driver Object, which I'm using an instance of.
I'm trying to Access the top menu on this site: http://store.demoqa.com/
The second menu element, "Product Category", has a submenu. I'm trying to emulate a mouse-over of the "Product Category" element, then select and click the first element in the list (Accessories).
This is what I've got so far, pieced together by several searches here and elsewhere. It works up the point of clicking on the menu item ("Accessories"). I see that the top element is selected, and that the menu item is "selected" because it slightly indents when hovering the mouse over it. However, from there I cannot seem to Click() it.
"menu-item-33" is the top menu item, Product Category.
"menu-item-34" is the sub menu item Accessories.
Actions action = new Actions(FFDriver.Instance);
IWebElement we = FFDriver.Instance.FindElement(By.Id("menu-item-33"));
action.MoveToElement(we).MoveToElement(FFDriver.Instance.FindElement(By.Id("menu-item-34"))).Click().Build().Perform();
It moves to the correct item, but the Click() function doesn't seem to work, since the page isn't changed.
Pardon me if this is too little information, but I've tried to keep it narrowed down to the code that seems to be the struggle.

I do not see why the code you have wouldn't work. However, you can try implementing some explicit wait if necessary. I have tried the following and it works. Note: I always suggest you to use id for locating element. But, I thought I show you another option and directly finding the anchor will be wiser for submenu item
By byId = By.Id("menu-item-33");
By css = By.CssSelector("a[href*='product-category/accessories']");
Actions action = new Actions(_driver);
IWebElement we = _driver.FindElement(byId);
action.MoveToElement(we).Build().Perform();
new WebDriverWait(_driver,TimeSpan.FromSeconds(2)).Until(ExpectedConditions.ElementIsVisible(css)).Click();

Related

Unable to locate element in Sitecore 8.1 (selenium and c#)

I'm trying to run some automated tests in Sitecore 8.1 using Chrome and Selenium and c#. My code doesn't want to find any elements within the Sitecore pages, specifically the experience editor.
I am encountering the "unable to locate element" warning.
For eg: an item I want to .Click() is the toolbar ribbon button to expose the toolbar menu.
Here's the element:
<a data-sc-id="QuickRibbon" data-sc-click="trigger:button:toggleshow" data-sc-command="" data-sc-сontrolstaterequest="" data-sc-controlstateresult="" data-sc-postponedcall="" data-sc-ispressed="false" class="sc-quickbar-item sc-quickbar-button sc_QuickbarButton_53 data-sc-registered" title="Toggle the ribbon." data-sc-pagecodescriptfilename="" data-bind="ispressed: isPressed, visible: isVisible, click: click, command: command, enabled: isEnabled" data-sc-require="/-/speak/v1/ribbon/QuickbarButton.js" href="#" style="float:right"><img src="/sitecore/shell/client/Speak/Assets/img/Speak/Common/16x16/white/navigate_down.png" alt="Toggle the ribbon."></a>
Here's its XPath:
/html/body/div/div/div[1]/nav[1]/a[3]
I have extended the wait time to allow it to become visible as it can take a few seconds to load these pages. But this didn't work.
I have tried:
driver.FindElement(By.XPath("/html/body/div/div/div[1]/nav[1]/a[3]/img")).Click();
which gave me the "unable to locate" error
driver.findElement(By.className("class="sc-quickbar-item sc-quickbar-button sc_QuickbarButton_53 data-sc-registered"")).Click();
which gave me an error about unable to use compounded classnames.
I've tried a whole host of other options/combinations trying to pick up the alt text etc but I just can't get it to pick up the element.
Any ideas? Let me know if you need any more info.
Thanks
Change this line
driver.findElement(By.className("class="sc-quickbar-item sc-quickbar-button sc_QuickbarButton_53 data-sc-registered"")).Click();
to below line :-
driver.findElement(By.className("sc-quickbar-item sc-quickbar-button sc_QuickbarButton_53 data-sc-registered")).Click();
Edited 1..
If compound class does not work here you can perform action by using xpath as below :-
var wait = new WebDriverWait(driver, TimeSpan.FromMinutes(1));
var clickableElement = wait.Until(ExpectedConditions.ElementToBeClickable(By.xpath("//a[#data-sc-id='QuickRibbon']")));
clickableElement.Click();
Edited 2..
You need to switch frame before perform action if your element is present inside a frame as below :-
driver.SwitchTo().Frame("your frame name or id");
Hope it will work...:)
following suggestions from #Software_engineer I have managed to write this which works:
Thread.Sleep(6000);
driver.SwitchTo().Frame(driver.FindElement(By.Id("scWebEditRibbon")));
var wait = new WebDriverWait(driver, TimeSpan.FromMinutes(1));
var clickableElement = wait.Until(ExpectedConditions.ElementToBeClickable(By.XPath("//a[#data-sc- id='QuickRibbon']")));
clickableElement.Click(); //click to drop down the toolbar
driver.SwitchTo().DefaultContent();
I needed to switch to the iframe!

selenium c# mouse over actions function

I have to mouse over a row to display a link that I need to click. I am able to mouse over the row and the link I need to click on is displayed but I can't click on it. Below is my code:
IWebElement element = driver.FindElement(By.XPath("//span[contains(text(), 'abc#gmail.com')]"));
System.Threading.Thread.Sleep(5000);
Actions action = new Actions(driver);
action.MoveToElement(element).Perform();
Thread.Sleep(5000);
IWebElement delete = driver.FindElement(By.XPath("//span[contains(text(), 'Delete')]"));
delete.Click();
I gather that there is a menu that pops up when you hover over that first "element" IWebElement. When using Java, I had a similar problem where a simple click() action on the menu item in that popup would not work. I had to resort to using Javascript. You could insert this line right after your code to retrieve the delete web element:
((JavascriptExecutor)driver).executeScript("arguments[0].click();", delete);
I'm guessing that you could do something similar with C#

Selenium - Force click on non-visible element

I'm using C# Selenium.WebDriver.2.44.0
On some 3rd party site I'm trying to press an element and get this:
var myWebElement = Driver.FindElement(By.XPath("//a[.=' some value']
myWebElement.Click();
I get the element and on click I get this:
{"element not visible\n (Session info: chrome=39.0.2171.95)\n (Driver info: chromedriver=2.9.248315,platform=Windows NT 6.1 SP1 x86_64)"}
The item is within some sub menu revealing after I successfully press the parent menu. Also put 5 seconds sleep to be safe that the accordion is well seen (and it is well seen in my eyes).
Question - on 3rd party site how can I force the click on this item?
You could try bringing it to the top by changing the z-index with driver.execute_script().
You could use the inbuilt functions and WebDriver waits
var myWebElement = Driver.FindElement(By.XPath("//a[.=' some value']
WebDriverWait wait = new WebDriverWait(Driver.FindElement, TimeSpan.FromSeconds(10));
var element = wait.Until(ExpectedConditions.ElementIsVisible(myWebElement));
Actions action = new Actions(Driver.FindElement);
action.MoveToElement(element).Perform();
myWebElement.Click();
The problem is that Selenium executes actions one after another, but something like "show a sub menu" is lost between actions.
You're likely going to have to use an Actions chain for this:
Actions action = new Actions(Driver);
action.MoveToElement(Driver.FindElement(By(ParentElementSelector)))
.click()
.MoveToElement(Driver.FindElement(By.XPath("//a[.=' some value'])))
.click()
.Build()
.Perform();
This will move to the parent element, click, then move to the element you wish to find, then click. It will perform all of these as one action, which should be able to click the sub menu element.
When an element is not visible u can try this...It works for me
IWebElement WEHiddenID = driver.FindElement(By.Id(""));
WEHiddenID.SendKeys(OpenQA.Selenium.Keys.Enter);

Selenium WebDriver SubMenu click not working

I am not able to Click on SubMenu item using selenium webdriver using c#.
I am using IE9 and FireFox 13.
I have tried Action Builder but it does not work.
It gives an error saying element cannot be clicked.
WebDriverWait Wait = new WebDriverWait(webDriver, TimeSpan.FromSeconds(5));
IWebElement menu = Wait.Until((d) => webDriver.FindElement(By.Id("id1")));
IWebElement menuOption = Wait.Until((d)=>webDriver.FindElement(By.Id("ID2")));
Actions builder = new Actions(webDriver);
builder.MoveToElement(menu).Build().Perform();
Thread.Sleep(5);
//then click when menu option is visible
menuOption.Click();
I have used even javascript :
js.ExecuteScript("return $(\"a:contains('ID1')\").mouseover();"); // Mouse hove to main menu
webDriver.FindElement(By.Id("ID2")).Click();
Please give some solution to click on hidden elements
You could use Expected Conditions to wait for element being clickable after hovering above it (Thread.sleep() is almost always the bad choice. And 5 ms won't be enough.).
The docs for this class (ExpectedConditions in OpenQA.Selenium.Support.UI namespace) are broken as I can see them now, but if you can follow the Java code in the link above, here are the Expected conditions for Java - it's really almost the same in C#, too.
Instead of using the statement Thread.sleep(). You can try to click on the element after making sure that it is displayed.
After you get the WebElement you want to click on , check if it is displayed by using the isDisplayed() method within the ExpectedContition statement about which #Slanec is talking about in the above post.
By this you can make sure you will click on the element only after Wait.Until() returns true. i.e the menuOption is displayed.
I'm writing the code in java as I do not know C#. But I guess you can figure out what I'm trying to say -
new WebDriverWait(driver, 60).until(new ExpectedCondition<Boolean>() {
public Boolean apply(WebDriver driver ) {
return driver.findElement(By.Id("ID2")).isDisplayed();
}
});
I hope that this helps you.

How to click an element (hyperlink) on a webform from C#, when it does not have any ID and Name

For the last two weeks I have been kind of stuck on a problem.
I am developing some web scrapers using C# and I am using a WinForms WebBrowser control in my application. I am able to fill up the web form which is opened in my browser and submit it automatically by using the following code:
HtmlElement submitButton = document.GetElementById("Element_ID″);
submitButton.InvokeMember(“click”);
So far everything is fine, but the problem is that there is one another element in the web form that I want to click too, but this element does not have any id or name so I don't know how to click this one.
Please help me as soon as possible I need it for my master thesis.
(I want to click the next page arrow button in the give website:
http://www.gelbeseiten.de/yp/11//subscriberlist_pageAction.yp?sessionDataString=H4sIAAAAAAAAAI2PQU8CMRCFfw0XSEmns9128k5KongwGjFeSZftIqILbhcVf70NSgg3X-pbyXjLfvCFpqsbbIMpwbVRRuaBELKm6iew5T4gLFUpdmKpewJAGD8xV7JaxalfpdZX6mP31bH4WQfZblJehXcd2tGvr0WwbunVIKbYIZjjKmoa3atct4RSh-pA/S912oY4qhWzyjJkLvPZV4P4JetNFHYWOG2OoCH4pZlyU-pjWdhjS/LY2sp7-p1lLCLOGXwTLqpT1XSqOiXcpE3Xzw-pncUtGSDNp0ZZwR0we92TxSHjIX0x-pIQM-p0AZuciLl7M/kGE-pmcGjIOsvEpTB-pADJS0suGAQAA&page=0&filterTrade=-&filterFunction=-&sortBy=sort_trade&availableLetters=ABCDEFGHIJKLMNOPQRSTUVW )
I've written many web-scrapers in the past using embedded WebBrowsers, so you've come to the right place.
When the element does not have a name you need to find it by either content, or another associated element that is named.
In the first instance we wrote helper methods to iterate the hierachy looking for a specific piece of content within an element.
For the second option you get the named element and use a specific index for the desired child.
A combination of both (find a specific parent then look for a child with the right content)
In your specific example webpage, the next page anchor has a class type of "arrow next" you can search for.
You could do
HtmlElement next_arrow = document.GetElementsByTagName("a")
.Cast<HtmlElement>()
.Where(e => e.GetAttribute("class") == "arrow next")
.FirstOrDefault();
if (next_arrow != null)
{
next_arrow.InvokeMember("click");
}
Here's a trick, not by InvokeMember("click") rather just "simulating the click" -
this is the link for the first page:
gelbeseiten.de/yp/11//subscriberlist_pageAction.yp?sessionDataString=H4sIAAAAAAAAAI2PQU8CMRCFfw0XSEmns9128k5KongwGjFeSZftIqILbhcVf70NSgg3X-pbyXjLfvCFpqsbbIMpwbVRRuaBELKm6iew5T4gLFUpdmKpewJAGD8xV7JaxalfpdZX6mP31bH4WQfZblJehXcd2tGvr0WwbunVIKbYIZjjKmoa3atct4RSh-pA/S912oY4qhWzyjJkLvPZV4P4JetNFHYWOG2OoCH4pZlyU-pjWdhjS/LY2sp7-p1lLCLOGXwTLqpT1XSqOiXcpE3Xzw-pncUtGSDNp0ZZwR0we92TxSHjIX0x-pIQM-p0AZuciLl7M/kGE-pmcGjIOsvEpTB-pADJS0suGAQAA&page=0&filterTrade=-&filterFunction=-&sortBy=sort_trade&availableLetters=ABCDEFGHIJKLMNOPQRSTUVW
as you see page=0; clicking next, gives the link -
gelbeseiten.de/yp/11//subscriberlist_pageAction.yp?sessionDataString=H4sIAAAAAAAAAI2PQU/DMAyFf00vmzLFdprE8gkmwTggEENcp3RNxxh0o-pmA8euJBlO1G0-p-pvCf58zNwUzW-pDKyQalSmckExl6DqJpKnPCEuVbDaYFUvBcEIFXgVu1Ws2nV6Xac-pZn89X5xFwoed2MvQbmI73rf1eL4L3SakFFsJOBpnzcJbte9W4hSI-pQ/S912oY4qhWz5LDSC992Dl/QR60ahPki2OZKeNfCgiba18oicmLV8lTcoS8t6BJ8zsHMo3yEU1VE1D1ZmWm7Tt-psXxtNwCMmjS4BhJ7oDAy72WR5CH/MT0l1HQEVa46QDK2Z/JsTyhcdIAWrZeGy8/k7LJ5YQBAAA-e&page=1&filterTrade=-&filterFunction=-&sortBy=sort_trade&availableLetters=ABCDEFGHIJKLMNOPQRSTUVW
now page=1
and so on... in general clicking next means page=(x+1) clicking prev means page=(x-1). so build a string according the requirements. this addresses ur problem, however there are some other data also sent with querystring, that u have to append to the string as well.

Categories