How to target multiple "li" with same classname - c#

Hi everyone the function of my code is to take a users shoe size preference and then click on an element on the page based on their size.
I will do this by taking numerical input from the user and store it in a value, then searching for the element that matches the size they have entered.
Here is the html code from the website I am using:
<div class="form product__form product__form--size product__form--last js-select-size-mapper">
<ul class = "product-size">
<li class = "js-size-value ">
8
</li>
<li class = "js-size-value ">
9
</li>
<li class = "js-size-value ">
9.5
</li>
<li class = "js-size-value ">
10
</li>
<li class = "js-size-value ">
10.5
</li>
</ul>
</div>
I always get some sort of error regarding how the element is not clickable. The weird part is sometimes the IWebElement declaration is verified (I mean there is no error in declaring it), sometimes there is an error when I try to click.
If you need to see a better example of code, hop over to the website here.
For example, when I run this code:
var element = driver.FindElement(By.XPath("//li[contains(#class,'js-size-value ')][contains(text(),size)]"));
element.Click();
*note, I have previously declared a variable called "size", and that's what I'm referring to when it says "(text(),size)]"
I get the error:
Additional information: Unexpected error. Element is not clickable at point (825.1500244140625, 45.69999694824219). Other element would receive the click: div class="header__wrapper">
I don't know how to approach this, and need some light shed on it in general. I have searched through stackoverflow for answers, and haven't found any posts that pertain to exactlty what I am trying to accomplish, or are vague and hard to understand.
Please take caution when answering that I am new to Selenium and C# in general, so if you could add a bit of detail in your answers and not assume I know what you are talking about, that would be great.

You accidentally set size as text instead of as variable. This means selenium will search a list item with the text 'size', which doesn't exist, instead of for example size 9.5,
var element = driver.FindElement(By.XPath("//li[contains(#class,'js-size-value')][contains(text()," + size + ")]"));

Related

What is the best way to pass a variable to a partial in the layout about the current page?

I've implemented a huge template to a new .Net Core MVC app and have separated it to various partials (header, sidebar, footer).
It works well - however, the side menu bar is meant to have
<li class="active">
on the currently visited page and change from:
<li class="treeview">
to
<li class="treeview active menu-open">
on any open section.
Other than loads of if statements or a lot of VERY messy code, I can't figure out how to do this. Can someone point me in the correct direction please?
You don't need if statements, but you will need to employ ternaries (i.e. some amount of conditional logic is required). The most terse way I've found to handle this sort of thing is with code along the lines of:
#{ string url; /* define anywhere, just needs to be before nav HTML */ }
...
#{ url = Url.Action("Foo"); }
<li class="#(Request.Path == url ? "active" : null)">
Foo
</li>
#{ url = Url.Action("Bar"); }
<li class="#(Request.Path == url ? "active" : null)">
Bar
</li>
The url variable is declared first just so 50,000 different variables aren't necessary. The URL is saved to a variable at all simply so you do not need to repeat any calls to Url.Action and such (i.e. one for the conditional and another for the actual link). Here, I'm just doing a direct comparison match, but you may want the list item marked active even if the current page is a sub item. For that you'd simply use Request.Path.StartsWith(url) instead as your conditional. However, don't use that on the link to your homepage (i.e. /) or it will always be marked active.
Follow the same approach with your "treeview" items.
#{ url = Url.Action("Item1"); }
<li class="treeview #(Request.Path == url ? "active menu-open" : null)">
Tree view item
</li>

Selenium find elements within specified element

I'm running into trouble with Selenium when it comes to XING's groups. The solution I was using for more than two years to this very date does not work anymore; they must have changed something about their HTML.
The main problem is that a certain select element doesn't open (when trying to open it by clicking it) and I hence cannot access the options to "click" or to select. I see a small border embracing the drop down, as if it was clicked but didn't function in second place.
Now that I've spent quite some time on elaborating on the error, I'm quite sure this is because the same (meaning the same attributes, ...) drop down exists on the same page at another point (to sort/filter posts shown by groups). However, I want to select the (sub) forum that a new post is submitted to, and this does not work.
I tried many, many, many different things of which none worked, obviously. I'm unable to list all of my attempts here since it's simply too much and partly too long ago. Some of what I tried:
select the drop down by various methods (CSS Selector, class name, XPath, ...)
access the desired option of the drop down directly (by CSS Selector, class name, XPath; even tried to collect arrays of all elements and select the right one by index, didn't work either)
access the desired option of the drop down directly by JavaScript and 'click' it by JS
And now SO is my hope. I thought of a way to select -exactly- this drop down (rather than the other one described) by child elements and so on (this is the reason for the title of this question).
This is the HTML:
<div class="comm-navigation forum-select is-open" id="new-post-forum-select" data-is-open="true">
<a href="#" class="comm-navigation-trigger">
<span class="comm-navigation-name" title="Select forum">Select forum</span>
<i class="comm-navigation-icn-closed foundation-icon-shape-arrow-down"></i>
<i class="comm-navigation-icn-open foundation-icon-shape-arrow-up"></i>
</a>
<ul class="comm-navigation-dropdown hidden" style="width: 519px; display: block;">
<li class="comm-navigation-group forum-list">
<ul>
<li class="comm-navigation-item">
<a href="/communities/forums/100941274" class="comm-navigation-forum" data-forum-id="100941274" data-forum-name="Members" title="Members">
Members
</a>
</li>
<li class="comm-navigation-item">
<a href="/communities/forums/100941276" class="comm-navigation-forum" data-forum-id="100941276" data-forum-name="Q & A" title="Q & A">
Q & A
</a>
</li>
<li class="comm-navigation-item">
<a href="/communities/forums/100941275" class="comm-navigation-forum" data-forum-id="100941275" data-forum-name="Feedback" title="Feedback">
Feedback
</a>
</li>
</ul>
</li>
</ul>
<input type="hidden" name="post[forum_id]" id="post_forum_id" value="">
</div>
I thought of perhaps going from comm-navigation forum-select is-open (which is the same when it's still closed without is-open) to the inner elements to get the right Chrome element and then click the option.
Also, I found that there's a hidden field:
<input type="hidden" name="post[forum_id]" id="post_forum_id" value="">
Which is exactly related to my problem; value is empty as long as nothing's selected, as soon as selected, the forum's id is inserted into the value. This I could imagine if there wasn't any JS that prevents you from submitting the form without having actually selected the sub forums by drop down.
Looking forward to great solutions.
If I understood the question, then first you need to click on the span inside the first link (class=comm-navigation-trigger) with the text "Select Forum". This makes the "ul" below to be visible. Now you need to click the desired "li" inside this list. If so then read on.
Find the span with the css selector - "div[id='new-post-forum-select'] > a[class='comm-navigation-trigger'] > span". Click on this element.
Wait for the list to become visible. Use the css selector - "div[id='new-post-forum-select'] > ul[class*='comm-navigation-dropdown']". Use the ElementIsVisible ExpectedCondition. Though you may or not require this step, added this as a check.
Find the link with the required value - "div[id='new-post-forum-select'] > ul[class*='comm-navigation-dropdown'] a[class='comm-navigation-forum'][data-forum-name='Q & A']". Click on this.

Hand coded C# Coded UI Test , Control/Object location issue

I have a dropdown menu sub-item ("logout") that I want to select. I need to hover over the menu first to make the logout link appear. There's a lot of div's surrounding it; the spy tells me it's an HTMLPANE, but there's no built-in support for HtmlPanes in VS code as far as I can see. (I try typing it in and intellisense doesnt recognize it, not from htmlcontrols namespace)
Just before trying to describe this main menu object, I'm defining the variable as an HtmlDiv. I've even tried to identify it generically by referring to it as an HtmlControl.
Here's the "view source" of the dropdown menu in question. I need to get to the "Logout" link which is the bottom option in the dropdown.
<li class="my-account-top" aria-haspopup="true" aria-owns="doormat-profile">
<span class="icon-profile menu"></span>
<span class="profile-header tablet-hide"> Profile</span>
<div class="ma-menu-items left">
<a id="nav-my-account-profile" href="/my-account/profile/">Edit Profile</a>
<a id="nav-my-account-profile-view-card" href="/my-account/profile/view-card/">View ID Card</a>
<a id="nav-my-account-profile-request-card" href="/my-account/profile/request-card/">Request ID Card</a>
<a id="nav-my-account-profile-logoff" href="/my-account/profile/logoff/">Log Out</a>
</div>
</li>
</ul>
I'm not familiar with the `mouse.hover function. Can you please show me an actual example, preferably from this code? I'm not even sure if this is a way to identify it because from what I observed by recording the hover, browser resizing changes the coordinates.
I don't know if I am obliged to give a coordinate to mouse.hover, or can I just specify the name of the object control? (i.e. mouse.hover(varnameformainmenu))

Access A Link Inside A NAV Element

I'm trying to access an HTML element using Selenium (C#) but I'm currently having trouble. The element is located within a structure like this:
<nav>
<ul class="menu"> id="menu">
<li id="ignore"> </li>
<li id="test_tab">
Update
</li>
</ul>
</nav>
I need to access and click "Update". What is the best method to access this link? I have tried .findElement(By.Id("test_tab")) and similar without success. Once it has been selected I then plan to call .click().
Thanks in advance.
Very simple! First you need to determine what element is receiving the click. in this case, the <a> will be. Just use a simple css selector.
driver.FindElement(By.CssSelector("ul#menu li#test_tab > a[title='Update']")).Click();
You are trying to select the li element and hence not possible to click the link. For selecting 'a' there could be multiple options.
1)
.findElement(By.LinkText("Update")).click()
2)
IWebElement update = driver.findElement(By.Id("test_tab"));
update = update.findElement(By.TagName("a"));
update.click();
3) You could use xpaths to directly select 'a'.

how to assign a class to one of the <li> in master page through c# from child page?

I have a master page with a bunch of menu like:
<ul id="ulMenu" runat="server">
<li id="A">
<li id="B">
<li id="C">
..and so on ..
</ul>
and i have a function in master page which i call from child pages, like:
Master.setCurrentMenu("A");
and in the SetCurrentMenu() of the Masterpage, since I have my < UL > set to run at server, i am changing it dynamically, like:
StringBuilder myMenu = new StringBuilder(ulMenu.InnerHtml);
//replace and add class for current page
myMenu .Replace("<li id=\"" + cp + "\"", "<li class='selected' id=\""+ cp +"\"");
ulMenu.InnerHtml = myMenu.ToString();
(where cp is the "A" in the current context)
This way I am changing the innerHTML and theoretically its supposed to work just fine. but, in my < UL > i have a few server tags in between like <% ... %> so now the asp.net tells me very cheerfully that :
The Controls collection cannot be modified because the control contains code blocks (i.e. <% ... %>).
What is the best thing I can do in this scenario?
Many thanks!
ps: edited this coz my < ul > were being taken as an html instead of showing up.. hmm
It's a known issue. I would suggest not using code blocks in this case (it's considered a best practice use as little code blocks as possible).
This link has the correct answer, infact, somebody can delete this question since its a repeated one, I dint realize it.
I finally got this to work via:
C# - How to change HTML elements attributes

Categories

Resources