Access A Link Inside A NAV Element - c#

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'.

Related

How to get an element that was created during page load?

I'm creating elements dynamically based on SQL data server side.
I want to also edit some of those element's attributes after their creation.
They way I'm trying to go about this is by generating a string with the elements and inserting it into a div's innerHTML:
client side:
<div id=master runat="server"></div>
server side:
string textToDiv = "<div id='" +num +"'><ul><li></li><li></li></ul></div>";
master.innerHTML = textToDiv;
Looks something like this in chrome:
<div id="master" runat="server">
<div id='1'>
<ul>
<li></li>
<li></li>
</ul>
</div>
<div id='2'>
<ul>
<li></li>
<li></li>
</ul>
</div>
</div>
Now, I want to change one of the child div's attributes. How do i go about doing that?
All I found on the internet is for more static uses using the method I applied when changing the 'master' div's innerHTML attribute. Is there a get() function or something similar to document.getElementByID() I can use?
a better way to solve this, to just simply place your script under the html code, but still in the body, this will make sure, the script is just loaded, when everything was rendered to the screen, with this, you can instantly access the elements and you dont have to use the window.onload eventlistener
I think you need to use the onload event and then use a function for create the Element.
window.onload() => {
element = document.createElement(" ");
element.setAttribute(" ");
element.innerHTML = ' ';
document.getElementById(' ').appendChild(element);
}
I hope it's can help you
Update and my solution:
I ended up just changing the attribute when generating the string. Used if() statements to change only the element I wanted.
Also, I moved the whole thing into a function and I'm calling the function on page load.
That way I can update the content without reloading the page.

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.

How to target multiple "li" with same classname

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 + ")]"));

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

ASP.NET / C# How to access list item of unordered list with runat=server?

I have a ul list with a number of list items like:
<ul>
<li runat="server" id="liOne">one</li>
<li runat="server" id="liTwo">two</li>
<li runat="server" id="liThree">three</li>
</ul>
On page load, I need to set these list items visible or not visible.
For some reason I cannot access these in the C# code behind. Nor are the list items being generated for the designer file. Does anyone have any suggestions how to get this to work?
I get this error:
The name 'liOne' does not exist in the current context
Many thanks.
It should work. Try rebuilding and restarting visual studio.
Then try deleting the designer file and right-clicking on the page and selecting "convert to web application" - if indeed it is already a web application.
Your code may be wrapped with some server control that does not allow direct references by ID. If so, you may access your inner elements of this wrapper by writing this:
var li = wrapperElement.FindControl("liOne") as HtmlGenericControl;
Hope this helps.

Categories

Resources