Selenium - Discerning Between Identical <articles>, C# - c#

I'm trying to have my program sit on a webpage and wait for specific tagName within an article to appear. Problem is, I need Selenium to check the article contains two tagNames before clicking it, that's where I'm stumped. The way I have my code setup right now, it doesn't click anywhere. It just sits on the page, I suspect because there's more than one article with the same main tagName that I'm trying to find. Here's the HTML:
<article>
<div class ="inner-article">
<a href ="/shop/shirts/iycbmgtqw/x9vdawcjg" style="height:150px;">
<img alt="Xrtqh7ar444" height="150" src="//d17ol771963kd3.cloudfront.net/120885/vi/xrTQH7Ar444.jpg" width="150">
</a>
<h1>
EXAMPLE_CODE
</h1>
<p>
EXAMPLE_COLOUR
</p>
</div>
</article>
All other items on this page have an identical class, and some have identical tagNames. I want to search for when there's a specific combination of two tagNames in an article. I realize xPath is an option, but I would like to code it before knowing an xPath, where the name of the item is the only available information.
And here's the code I'm working with at the moment:
driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromMinutes(10));
IWebElement test = driver.FindElement(By.TagName(textBox12.Text));
test.Click();
where textBox12.Text is "EXAMPLE_CODE". Am I correct in assuming that WebDriver doesn't click anything because there is more than one element with the tagName "EXAMPLE_CODE", and is there a possible way to make it first look for "EXAMPLE_CODE" and then check the secondary: "EXAMPLE_COLOUR"?
Thanks!!

You are using By.TagName incorrectly. Tag refers to the type of element you are trying to find. In this case for the link it is 'a'. Or in case of a div it is 'div'. Te correct way of finding with tagname for a link would be - By.TagName("a").
You need to match text and you will need to use xpath. Assuming that the code is unique you should try.
XPath to get the code href -- //div[class='inner-article']/h1/a[.=EXAMPLE_CODE]
XPath to get the color href -- //div[class='inner-article']/h1/a[.=EXAMPLE_CODE]/following-sibling::a

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

Selenium Automation unable to enter username in Way2Automation website

I am trying to do registration for this site
Registration page is inside a popup page.
HTML Code:
<fieldset>
<label>Username:</label>
<input name="username" required="" type="text"/>
</fieldset>
When I try to find the element using below tried code, element is not getting find.
driver.FindElement(By.XPath(".//*[#id='load_form']/fieldset[1]/input")).SendKeys("Kal");
I have also tried this with using CssSelector, but facing the same issue.
driver.FindElement(By.CssSelector("div#load_box form#load_form input[name=username]")).SendKeys("kal");
When I execute above code, I have got an error like element not visible
Can anyone help me on this issue?
Try this below code using xpath locator
driver.FindElement(By.XPath("//input[#name='name']")).SendKeys("Kal");
Explanation of xpath:- Use name attribute of <input> tag.
Suggesstion:- Instead of using absolute xpath, use relative xpath.
Note:- Before reach to this web-element provide some few seconds of wait, so your driver may able to find the web-element. So, you will not get an error like element not visible
Use below xpath:
//*[#id='load_form']/fieldset[6]/input[#name='username']
that site has 2 forms with the id load_form so you're getting the first one which isn't visible since it's the login form. You want the second one which is the register form.
you can use a selector to grab one of the fields that exists on the registration page and then move up to it's parent form and get all descendants that are fieldsets to fill out.
Here is the xpath you can use to pass the text "Dev" into the field labelled with "Name".
driver.findElement(By.xpath("//div[#class='fancybox-overlay fancybox-overlay-fixed']//form[#id='load_form']/fieldset/input[#name='name']")).sendKeys("Dev");
Let me know if this answers your question.
The problem is that there are two username INPUT fields. The way I typically handle this is to find a parent of the element that I want that has an ID or something unique that will distinguish the two elements. In this case, you can use a simple CSS selector,
#load_box input[name='username']
Note the load_box ID that distinguishes the two INPUTs.
Ajax popup on way2automation site is a tricky one because if you look for the username field by name By.name("username"), you will end up with 2 elements - one for username from signup popup, one from singin popup. To avoid this you have to explicity mention the correct element. This can be done via the following code:
webDriver.get("http://way2automation.com/way2auto_jquery/index.php");
WebDriverWait wait = new WebDriverWait(webDriver, 10);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("a[href='#login'"))).click();
wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector(".ajaxlogin input[name='username']"))).sendKeys("my_username");
As you can see in the code I am using class of the login popup - .ajaxlogin. I have used Java, but the concept is the same - you have to refer to the username element via css selector with popup class included: By.cssSelector(".ajaxlogin input[name='username']")

Not able to locate input element using Selenium WebDriver

I am new to Selenium. In a specific scenario I am not able to catch an input element. below is the code:
<ul class = "form1">
<li class="firstName">
<input placeholdervalue="First name" tabindex="1" placeholder="First name" class="text" placeholdevalue="First name" data-input-rule="name" data-value-rule="required" maxlength="20" type="text">
</li>
</ul>
I want to locate input element. I tried locating it using locator By.ClassName, By.CssSelector("input[class='text placeholder']") and also tried:
wait.Until(ExpectedConditions.ElementIsVisible(By.CssSelector("input[className='text' and placeholdevalue='First name'"))).SendKeys("Vipul");
but input element is not getting selected.
Please let me know the right way to select input element.
I would use a dot notation to match the classes of ul, li and input elements:
By.CssSelector("ul.form1 li.firstName input.text")
If the element still cannot be found, then there could two most commonly met reasons:
it is inside an iframe and you need to switch to it
you need to wait for the element to appear
I'll expand these items in case you would still have problems finding the element.
Thanks for the reply.
It worked with this,
driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(20));
wait.Until(ExpectedConditions.ElementIsVisible(By.CssSelector("ul.form1 li.firstName input.text"))).SendKeys("Vipul");
Is this the right way of using wait?
Also, can anybody point out to resources which explain working with frames using selenium webdriver?
-Amit

Getting element by Id

Selenium, NUnit testing, C#, Visual Studio.
How, in Selenium WebDriver, can I locate element in a page source that looks like following, and set some text in its <p> tag:
<body contenteditable="true" class="cke_editable cke_editable_themed cke_contents_ltr cke_show_borders" spellcheck="false">
<p></p>
</body>
This is body tag from CKEditor component present on a page (not a main page <body> element ).
Actually, I need to set some text in <p> element. What is confusing to me , is that class attribute is complicated, contains from several strings. I am aware of command: driver.findElement( By.className( "some_class_name" )); but how to use it in this case and to set some text in <p> element?
If you give the p tag an ID like so
<p id="derp">Text here</p>
You can send text to it using Selenium like this
driver.find_element_by_id("derp").sendKeys("herp");
Hope this helps!
EDIT: Without adding an ID to the element, you might be able to do something like this
driver.findElement(By.className("some_class_name")).findElement(By.tagName("p")).sendKeys("herp");
If you want the p elelement then this relative xpath should work.
//body[#class='cke_editable cke_editable_themed cke_contents_ltr cke_show_borders']/p
That is assuming that there is only a single body element with this class attribute.
As you are saying, there is no id usable for location, so you have to come up with a different solution.
Selenium is capable of using css selectors - it's the same scheme found in CSS files to specify to which elements the following styling rules should apply.
One possible locator would be the following:
body.cke_editable.cke_editable_themed.cke_contents_ltr.cke_show_borders > p
Advantage over XPath: CSS selectors are aware about groups, so they don't handle them only as strings. Using just an XPath expression against the exact class attribute, your recognition would fail if there would be another, new class withing the attribute. Using CSS selectors, it's possible to really just identify per class.
Simplified and boiled down to the classes that really describe your editable element, the following should be sufficient:
body.cke_editable.cke > p

Selenium to read the content from website

I have some contents like this in a webpage.
Appname Description Price Part Number Validity
App1 some desc1 25 JH32 30
App2 some desc2 250 PB36 180
App2 some desc3 20 QL76 10
App3 some desc4 50 KQ3J 30
My application is like after starting the app, user will enter an app name in which selenium will search for that particular appname in this site. What I want beyond this step is that:
Whatever appname I search for, selenium must retrieve the values corresponding to that fields such like selenium should retrieve the values of Price, Validity and Part Number fields. I tried selenium to retrieve the value by using attributes like classname, tagname, id etc. But all the fields have the same attribute for each of these fields, which makes selenium confusing to select the field.
Only thing I could find different is innertext which I can't use here since I can't predict what the user will give as the appname in the searchbox at the start of my application.
My sample html code, which I got once I clicked a field(price) in my site. I used firebug for this. and i am using firefox browser for selenium..
<td height="100%" class="ms-vb-title"><table height="100%" cellspacing="0" surl="" uis="512" cid="0x0100DFF86ACBE51BE549AA56639FCC32D7E0" ctype="Item" ms="0" csrc="" hcd="" couid="" otype="0" icon="icgen.gif||" ext="" type="" perm="0x1b03c4312ef" dref="sites/SoftwareDev/IAG/IAS/Lists/Unify Parts" url="/sites/SoftwareDev/IAG/IAS/Lists/Unify%20Parts/27_.000" id="27" ctxname="ctx1" onmouseover="OnItem(this)" class="ms-unselectedtitle"><tbody><tr><td width="100%" class="ms-vb"><a target="_self" onclick="GoToLink(this);return false;" href="/sites/SoftwareDev/IAG/IAS/Lists/Unify%20Parts/DispForm.aspx?ID=27" onfocus="OnLink(this)">MindMeister - 251-500 Pupil License<img height="1" border="0" width="1" alt="Use SHIFT+ENTER to open the menu (new window)." class="ms-hidden" src="/_layouts/images/blank.gif"></a></td><td><img width="13" alt="" style="visibility:hidden" src="/_layouts/images/blank.gif"></td></tr></tbody></table></td>
How can I achieve what I said?Any comments would be really appreciated..
Without seeing the HTML or your code, I would assume that the table you provided is set up in an ordered <table><tr><td>...</td><td>...</td></tr></table> form. Under this assumption, you could just use the code you are already using to find the appname, and then use the webdriver's Xpath/Jquery (based on which browser you're using) locating ability to find the appropriate data value by <td> index of the <tr> you found the appname element to be a child of.
When you have the element "selected", just return the label value and save it in a variable in your code.
If all you have to go on is the app name, then you need to do it like this:
Identify the WebElement which is the table cell (td) contains the app name.
Use a relative xpath to identify the next table cell along.
Extract the text from that table cell.
Repeat steps 2-3 all along the row.
Here is some simplified webdriver code to show in principle how it works:
WebElement td_appname = driver.findElement.ByLinkText("MindMeister - 251-500 Pupil License");
WebElement td_appdescription = td_appname.findElement.Byxpath("./../td[2]");
String appdescription = td_appdescription.getText();
Here, the crucial bit is that xpath on the third line of code. That will only work on a very simple table structure (table/tbody/tr/td); but yours is a lot more complicated, so you will need to work out the appropriate relative xpath for your website's structure. I recommend using a good browser's developer tools (e.g. on firefox, use firebug and firepath) to take a good look at the DOM tree and figure out what kind of xpath you will need to go from one cell to the next.

Categories