Finding Button within Button Group Class Using Selenium Webdriver in C# - c#

My end goal is to be able to click Yes or No on a webpage.
Using fire bug I can see the Yes and No buttons reside in a class called "btn-group"
<div class="btn-group btn-group-default answer-toggle" aria-label="..." role="group">
<button class="btn ng-pristine ng-valid active btn-secondary ng-touched" btn-radio="true" ng-model="consultation.previousSoundVoid" ng-class="{'btn-secondary': consultation.previousSoundVoid}" type="button">
Yes
</button>
<button class="btn ng-pristine ng-untouched ng-valid" btn-radio="false" ng-model="consultation.previousSoundVoid" ng-class="{'btn-secondary': consultation.previousSoundVoid == false}" type="button">
No
</button>
</div>
I think I could find Element by XPath but I am trying to improve my Selenium skill.
I am hoping there is a way to first find the "btn-group" class then somehow choose Yes or No within that.
Or be able to create variables for both the Yes and No options. If I do:
var button = Driver.Instance.FindElements(By.ClassName("btn"));
It returns 21 options. I found that:
button[15].Text returns "Yes"
button[16].Text returns "No"
Instead of having to look through all 21 results and worrying about if the index changes, can I search the results by text somehow?

The best way is to identify those element using text and xpath since they do not have any unique id
//button[.='Yes']
Desperate to use cssSelector?
.btn.ng-pristine.ng-valid.active.btn-secondary.ng-touched
since it is a compound class
You can also go for nth-child() with css
[role='group']>button:nth-child(1)
whereas 2 will let you select the button with text No

Case 1: When answer-toggle is unique in the HTML page
Driver.Instance.FindElements(By.XPath("//div[contains(#class,'answer-toggle')]//button[contains(text(),'Yes')]")).Click();
This will first locate a div that has answer-toggle in its class name and the find a button that has text Yes
Case 2: answer-toggle is not unique in your HTML page the you can use the complete class name as follows
Driver.Instance.FindElements(By.XPath("//div[#class='btn-group btn-group-default answer-toggle']//button[contains(text(),'Yes')]")).Click();
or
Driver.Instance.FindElements(By.XPath("//div[#class,'btn-group btn-group-default answer-toggle']//button[contains(text(),'Yes')]")).Click();
Case 3: If there is only one button in your HTML page that has text "Yes"
Driver.Instance.FindElements(By.XPath("//button[contains(text(),'Yes')]")).Click();
Same thing applies for No button. You just have to replace Yes with No.

There are definitely multiple options to locate the buttons, but I think that answer-toggle class sounds a good thing to rely on:
var buttons = Driver.Instance.FindElements(By.CssSelector("div.answer-toggle button.btn"));

Related

Not able To click in selenium browser with C#

Button type is Input.
<input type="submit" value="Send" class="wpcf7-form-control wpcf7-submit btn solid">
I want to click this Button using code, try to click on Button By ClassName.
My code is as per below but not get any success.
string url1 = "myUrl";
IWebDriver driver = new ChromeDriver(Application.StartupPath);
driver.Navigate().GoToUrl(url1);
driver.FindElement(By.ClassName("wpcf7-form-control .wpcf7-submit btn solid")).Click();
This throws the following error :
Compound class names not allowed. Cannot have whitespace in class name. Use CSS selectors instead. and not use single class because there is a other class with same name.
driver.FindElement(By.XPath("//input[#type='submit']")).Click();
I would try to avoid using XPath, Instead I would add an Id to your input.
The reason being XPath is more likely to be changed over time than Id.
Also if you add another element with the same HTML, selenium will not be able to differentiate between them and will always select the first element.
Using Id also makes your code more readable.
You can try this:
<input type="submit" value="Send" Id="YourButtonId" class="wpcf7-form-control wpcf7-submit btn solid">
And
driver.FindElement(By.Id("YourButtonId")).Click();

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.

Selenium - Discerning Between Identical <articles>, 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

C# - PhantomJS/Selenium - Click event doesn't register on a button inside a modal

I'm having some issues with automating a website using PhantomJS/Selenium WebDriver in C#.
Part of the website has a check on addresses; entering in an address it can't verify (or just not entering an address at all) brings up a modal div with buttons in it. Depending on the situation, it will either give you the closest address, or the option to just continue without an address, but the button always has the same id. The HTML for this div (for the "no address entered" version) is here:
<div id="confirmAddress" class="col-xs-5 active-popupbox">
<div class="row vert-offset-top-2">
<p style="margin-left:55px;" class="h3">No Customer Address Provided</p>
<br>
<div style="margin-left:42px;margin-bottom:0px;" class="modal-body">No Customer Address Was Entered. We recommend having the Customer provide an address.</div>
<br>
<div class="col-xs-6">
<button type="submit" class="btn btn-default" style="margin-left:45px;width:200px;" id="confirmBack" name="confirmBack" align="center">Enter Address</button> </div>
<div class="col-xs-6">
<button type="submit" class="btn btn-default" id="confirmPopUp" name="confirmPopUp" align="center">Proceed with No Address</button>
</div>
</div>
</div>
The button I need to click is the last button, <button type="submit" class="btn btn-default" id="confirmPopUp" name="confirmPopUp" align="center">Proceed with No Address</button>
However, despite seemingly being able to find the element in my code and calling Click() on it, grabbing screenshots show that it apparently doesn't register the click since the modal popup stays on the page and the next part errors out due to not finding the elements I'm asking it to find.
Here is the relevant portion of my code:
File.WriteAllText(#"C:\Users\user1\Documents\Testing\source0.html",
_driver.PageSource);
_driver.FindElementById("contactinfo_next").Click();
if (_driver.FindElementByClassName("active-popupbox").Displayed)
{
_driver.GetScreenshot().SaveAsFile(#"C:\users\user1\documents\testing\screenshot01.png", ImageFormat.Png);
_driver.FindElementById("confirmPopUp").Click();
}
_driver.GetScreenshot().SaveAsFile(#"C:\users\user1\documents\testing\screenshot02.png", ImageFormat.Png);
I use the class name to find the div since they apparently have different id's depending on whether the address was "not provided" or "wasn't verifiable but a close match was found", but the class is always the same.
I have PhantomJS grabbing the source before clicking the "contactinfo_next" button, which is what brings up the modal div, and have confirmed that no div with class "active-popupbox" exists before the contactinfo_next button is clicked. "screenshot01.png" does get saved, which means that it is finding the div... but it still doesn't register the button click.
I have tried clicking other elements in the div to bring it "into focus", calling Click() twice on the button, assigning the div to a variable called div and then finding the button using div.FindElements(By.Id("confirmPopUp")) and clicking on each element in the collection, nothing has worked.
Has anyone else run into this issue?
Thanks!
EDIT: I'm using the following NuGet packages for this:
PhantomJS
Selenium WebDriver PhantomJS cross platform
Selenium WebDriver Support Classes
Selenium WebDriver
Okay so I don't know if this is specific to this site that I'm trying to automate, but resizing the PhantomJS viewport worked - in my screenshots, the modal's buttons were overlapping each other. Not sure why it matters but this is what ended up solving my problem. ¯\_(ツ)_/¯
To resize the viewport (requires System.Drawing):
_driver.Manage().Window.Size = new Size(1920, 1080);
Hope this helps anyone else who has a similar problem in the future

Execute a java script to make an element visible

I'm trying to automate the use of a website using Selenium, at one time I want to click on a hidden button defined this way :
<body>
<div class="smenu" id="smenu4">
<input tabIndex="-1" type="button" onclick="SearchEng" value="FindEng" />
<!--> Lots of inputs <!-->
</div>
</body>
I already tried to simply click the button, but it doesn't work. I can select it and retrieve information though. That's why I'm now trying to run a javascript to make the button visible before clicking it. Here is my code :
IWebElement element = driver.FindElement(By.XPath("//div[#id='smenu4']/input[#value=FindEng"));
String js = "arguments[0].style.height='auto'; arguments[0].style.visibility='visible';";
((IJavaScriptExecutor)driver).ExecuteScript(js, element);
The thing is nothing happens when I launch it. Is it possible that I can't run scripts ? Can you run them on any website ? - I use internet explorer 11, windows 7. Thanks !
Inspect the element in your Browser and check that what is the reason that the element is invisible. Or just simply compare the element when it is visible or not. Possible reasons:
The element is not in the DOM yet.
The element hasn't got width and/or height.
visibility parameter. (http://www.w3schools.com/cssref/pr_class_visibility.asp)
display parameter. (http://www.w3schools.com/cssref/pr_class_display.asp)
When you know the reason, you will know the solution :)

Categories