How to Find.By a non-standard attribute with Watin? - c#

I am using WatiN to test a site.
There is a checkbox that I need to verify whether it is checked or not, then act on it accordingly.
When the checkbox is checked, the HTML shows
<input type="checkbox" name="bean.enabledContentTypes" id="jive-form-choose-contenttypes-1" value="1" checked="CHECKED"/>
I see that I can use 'Find.ByID' or 'Find.ByName' and a bunch of other 'Find.By...' options, but there isn't one for 'Find.ByChecked'.
How can I Find by this apparently non-standard attribute?
My only idea (that I can't figure out) is to store the entire element, and then somehow check the Element as a string (not sure how to do this anyways) and see if Element.Contains("checked").
Seems like there's probably a more poignant way to do what I'm am after?

I found the answer:
Find.By("attribute name", "attribute value")
So for my purposes, it is:
ie.TextField(Find.By("checked", "CHECKED")).Click();

Related

How to find IDs, Names, Classes of CSS Elements with Selenium

Im struggling with the problem, that i cant really figure out, where i should look for the indentification of an specific element. In a lot examples i found in the internet, most of the elements have clear ids, names and so on.
The webpage im testing right now, has elements which have no ids or names. They have most of the time just a "type", "class" and other.
I know, that i can use "class" as the identification, but after talking with a coworker today, he suggested me, not to use class in find element as those are CSS classes which appear more than one time on the webpage.
Heres an example of a inspect of a searchfield i would like to get the identification from.
<input type="text" class="mud-input-slot mud-input-root mud-input-root-text mud-input-root-adorned-start" placeholder="Search here" _bl_7285135c-aa68-4a79-981f-4ee1af405a95="">
I used for now this, which does work.
webDriver.FindElement(By.XPath("//input[#placeholder='Search here']")).SendKeys("Super");
But in other elements, im using "class" in XPath which i would like to change. Example of such is here:
Inspect of a text field:
<input type="text" class="mud-input-slot mud-input-root mud-input-root-text mud-input-root-margin-normal" placeholder="Name" _bl_b3249641-8126-4e48-a3fd-9fd64aa2fb80="">
And currently im finding the element with:
IWebElement TitleField = webDriver.FindElement(By.XPath("//input[#class='mud-input-slot mud-input-root mud-input-root-text mud-input-root-margin-normal']"));
My coworker mentioned also, that i can right click in spectace on an element, click on copy and choose there either "copy selector" or "copy XPath".
But when i click on "copy XPath", ill get this:
/html/body/div[2]/div/div/div/div[1]/div[2]/div/div/input
Or for selector this:
body > div.mud-layout > div > div > div > div.mud-toolbar.mud-toolbar-gutters.mud-table-toolbar > div.mud-input-control.mud-input-input-control.mt-0 > div > div > input
Is this something i could also use in FindElement?
What are another possible ways to identify a element in my example?
Locators automatically generated with dev tools are useless in most cases.
You have to learn how to create proper, exact, strong and efficient locators.
We mostly locating web elements with CSS Selectors or XPath.
In most cases you will have to use element tag AND some or several element attributes altogether to get an unique locator.
Very often you will have to indicate some unique parent element properties to reach that element.
So normally, in real life, element locators are looking like
//div[contains(#class,'ApplicationsView')]
or
//li[contains(#class,someClass')]//div[contains(#class,'thisClassName')]
or even like this
//div[contains(#class,'ObjectList')]//div[contains(#class,'ListItem')]/span/..//i[contains(#class,'active')]
You should try this
IWebElement menu = CurrentDriver.FindElement(By.CssSelector("div[class='menu-panel right']"));
Your first question :
Is this something i could also use in FindElement? - Yes You can. But that would be a terrible xpath since it is a absolute xpath. Tell your coworker that we should always use relative xpath.
Read here what is the difference between Absolute xpath and Relative xpath
Your next question :
What are another possible ways to identify a element in my example? - I would go with css selector.
for this HTML :
<input type="text" class="mud-input-slot mud-input-root mud-input-root-text mud-input-root-margin-normal" placeholder="Name" _bl_b3249641-8126-4e48-a3fd-9fd64aa2fb80="">
simply write css selector as :
input[placeholder='Name']
In your C# it would be something like this :
IWebElement NameField = webDriver.FindElement(By.CssSelector("input[placeholder='Name']"));
NameField.SendKeys("Your name");

How to locate the input box using C# Selenium

I need to find the input box in this HTML:
<div id="employeesDataTable_filter" class="dataTables_filter">
<label>
<input type="search" class="form-control input-sm"
placeholder="Filter..." aria-controls="employeesDataTable">
</label>
</div>
But for the life of me cannot - please help,
I have successfully written bags of tests and found many page element of different types but this one has stumped me.
I am very new to this and have tried
By ExecutiveSearchBox = By.XPath("//input[#type='search' and
class='dataTables_filter']");
You have encountered problems because you are selecting class attribute on input node instead on div. Try following selector:
//div[#class='dataTables_filter']//input[#type='search']
Also as #Marco Forberg mention it is good to use contain() XPath function in case if there are multiple classes provided for element:
//div[contains(#class, 'dataTables_filter')]//input[#type='search']
I hope it'll help to resolve your issue :)
To find the input element in your html snippet, you simply use
FindElement( By.CssSelector( "input" ) )
But note:
not always is the input box editable after page load is completed, it may take some time. It might be wise to wait until the box becomes editable if you want to send data to it.
not always does the input box appear immediately in the DOM. With modern UI like Angular, it might be not there immediately, might be something else for a while and only later become an input field and the like. Also here, making use of Seleniums wait functionality sure is a good idea.
I ALWAYS wait for the DOM state I expect and only after some time when the state is not achieved I throw.

textarea asp-for doesn't display property

I've been working on a small school project and decided to use .net core (MVC) for the first time. I have a small button I can click which executes the "ipconfig" command in the background and displays the output in a text area. At first my team partner used only a
public string Result;
in ViewModel for the view. In the view it's displayed via
<textarea asp-for="Result"></textarea>
So I decided to make it into a property with default get and set:
public string Result { get; set; }
But when I do that, the output doesn't show up in the textarea if I keep the same approach in the view as my team member did when he used a field instead of a property. Instead I have to do it like this to get it to show up in the textarea:
<textarea>#Model.Result</textarea>
Now I'm asking myself why this happens. Can't I display Properties with asp-for? And what would be better to use, a field or a property as Result?
Many thanks in advance!
In my case this behavior was happening because I did not have a separate closing tag on my textarea. I know your example above has it when using the asp-for method, but in case that was a copy/paste error, you may want to look at that again.
<textarea asp-for="Message" type="text" class="form-control" rows="5" id="MessageInputField" autofocus></textarea>
As opposed to:
<textarea asp-for="Message" type="text" class="form-control" rows="5" id="MessageInputField" autofocus />
This is incredibly annoying 'gotcha' like behavior in my opinion. And maybe if someone wants to tell me why it isn't, then please enlighten me, I'm always willing to learn.
You should actually be using properties, and if <textarea>#Model.Result</textarea> works, <textarea asp-for="Result"></textarea> should as well. The only reason it wouldn't is if the ModelState has a different value for Result (as the latter form actually uses ModelState, whereas the former is obviously using Model directly).
ModelState is composed of values from Request, ViewData/ViewBag, and finally Model, so for example, if you were to do something like ViewBag.Result = String.Empty, that would actually override the value from Model in ModelState.
There's no enough code here to truly diagnose the exact issue, but I would look for other places you might be using "result" (case-insensitive). If you're accepting that as a request param or setting a ViewBag member, etc. that's your problem.
I find this is a bit weird in .Net Core 6, when I want two-way binding - ie displaying the result
With asp-for I have to self close the tag AND add the additional textarea close tag to get the result displayed.
<textarea asp-for="Result" />#Model.Result</textarea>
This works but is not syntactically correct.
Without the self-close tag, the result was not being display
<textarea asp-for="Result">#Model.Result</textarea> #*Does not display the value*#
For display only, this is more correct
<textarea>#Model.Result</textarea>

C# GeckoWebBrowser v45 - set focus element on WebPage

I have a big problem and i need solution
I have html code on the web page:
<input class="fPersonalInput" name="email" id="email" value="" data-value="adres e-mail" maxlength="33" type="text">
I don't know how to set focus on this element
Any help is much appreciated........Thanks in advance
Use selenium.FindElement(by.XPath("xpath"))
To get the xpath of the element use the developer tool of chrome and do right-click in the element Copy>Copy XPath
I think what you need is to:
1) Get the element reference
2) Call Focus() method
(Browser.Document.GetElementById("email") as GeckoHtmlElement).Focus();
However, if you need to set the focus in order to set its value, be sure not to use any 'SendKeys()' method or similar, but rather just set the value like that:
(Browser.Document.GetElementById("email") as GeckoInputElement).Value = "busy#the.moment";

Fill a form with WatiN in C#

that's my first question, i hope i'm doing everything correctly.
Anyway, i have a weird issue. I basically have this HTML input which i want to fill with WatiN :
<input name="edit[id]" class="form-text required" id="edit-id" type="text" size="60" maxlength="64" value="">
That's my code in C# :
IE ie = new IE();
ie.GoTo(urlhere, just too long);
ie.TextField(Find.ByName("edit[id]")).TypeText("Text");
It's not working and it returns this exception :
Ulteriori informazioni: Could not find INPUT (hidden) or INPUT (password) or INPUT (text) or INPUT (textarea) or TEXTAREA element tag matching criteria: Attribute 'name' equals 'edit[id]' at about:blank
I'm not sure why it gives "at about:blank" honestly. I tried with a random google page and the code it's working. If i put a random name instead of the correct one, it gives me the same exception but with the correct url instead of "about:blank".
Note : I'm trying to fill a form.
Thanks for your help!
Not sure what web page are you using but from the information you posted it looks like that form might be "somewhere else" (another div, frame, etc.) To be able to find the EXACT entry you should press F12 (IE) or CTRL+SHIFT+I (Chrome) and traverse the HTML web page to find the exact portion were the input lies and you will find the exact spot.
The code you posted is perfectly fine, there's nothing else you need to do to make it work. If you need more help, posting the webpage you are trying to use will go a long way (if possible, of course).

Categories