I am doing automatic test and i want to check the occurrence of an alert with the inscription "Good morning" (when i do assert).
I am writing test in C# with selenium-webdriver.
How should I find a reference to that object?
I am using: driver.FindElement(By. ......
Element:
<div class="alert alert-dismissable alert-info">
<button aria-hidden="true" class="close" data-dismiss="alert">×</button>
Good morning
</div>
You can't query the text directly using css selectors. See this answer. What you can do is get all the elements with that class, and then iterate over them looking for the text.
var alerts = driver.FindElements(By.CssSelector("div.alert.alert-dismissable.alert-info"));
Assert.IsTrue(alerts.Any(element => element.Text.Contains("Good morning")));
Related
I used the following code to be able to click on the job link on the C # code but it couldn't find it.
C#:
1. driver.FindElement(By.PartialLinkText("Jobs List")).Click();
2. driver.FindElement(By.CssSelector("a[href*='jobs']")).Click();
3. driver.FindElement(By.XPath("(//a[#href='/jobs'])")).Click();
HTML:
<a href="/jobs" class="pr-0 pl-1 left-menu-item v-list-item v-list-item--link theme--light" tabindex="0">
<div class="v-list-item__icon">
<i aria-hidden="true" class="v-icon notranslate mdi mdi-credit-card-multiple theme--light white--text"></i>
</div>
<div class="v-list-item__title">Jobs List</div>
</a>
Please help me. Thank you.
Your locator seems correct. If you are encountering "No Such Element Exception", try to add implicit wait driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(30);
i just want to click button in my page.
The html code lookls like :
<tr ng-repeat="row in rowCollection" ng-class="{ "error-row": row.errorMessage }" ng-style="vm.getColor(row)" class="ng-scope" style="background: rgb(255, 242, 255) none repeat scroll 0% 0%;">
<td class="ng-binding">Wylaczenie nadan RDF</td><td class="ng-binding">WAITING_FOR_NOTIFICATION</td>
<td>
rfsSendingExecutor
</td>
<td class="ng-binding">2017-09-06 11:14:12</td><td class="ng-binding">2017-09-06 11:14:13</td>
<td has-role="REQUEST" class="text-center">
<!-- ngIf: row.inXml || row.outXml -->
<button ng-if="row.inXml || row.outXml" ng-click="vm.showXml(row)" title="Show" class="btn btn-xs ng-scope"><span class="fa fa-code"></span></button>
<!-- end ngIf: row.inXml || row.outXml -->
</td>
<td has-role="ERROR" class="text-center"><button ng-show="row.errorMessage" ng-click="vm.showError(row.errorMessage)" title="Show" class="btn btn-xs ng-hide"><span class="fa fa-search"></span></button></td>
<td class="text-center">
<button ng-show="vm.enableCancel(row)" ng-click="vm.cancelTask(row.workItemId)" title="Cancel" class="btn btn-xs ng-hide">
<span class="fa fa-ban text-warning"></span>
</button>
<button ng-show="vm.enableRepeat(row)" ng-click="vm.repeatTask(row.id)" title="Repeat" class="btn btn-xs ng-hide">
<span class="fa fa-refresh text-success"></span>
</button>
<button ng-show="vm.enableRepeat(row)" ng-click="vm.repeatTaskWithParams(row.id)" title="Repeat with parameters" class="btn btn-xs ng-hide">
<span class="fa fa-refresh text-warning"></span>
</button>
<button ng-show="vm.enableSkip(row)" ng-click="vm.skipTask(row.workItemId)" title="Skip" class="btn btn-xs">
<span class="fa fa-angle-double-right text-success"></span>
</button>
</td>
</tr>
All i want to do is click this button :
<button ng-show="vm.enableSkip(row)" ng-click="vm.skipTask(row.workItemId)" title="Skip" class="btn btn-xs">
<span class="fa fa-angle-double-right text-success"></span>
I've been through the xpath tutorials and checked many other posts nad forums. I'm not sure what I'm missing. I'm simply trying to find the following element by xpath like this :
button_to_click= findElement(By.xpath("//button[#title='Skip']"));
but it doesn't work. QUESTION : Why it don't work only by title?
I try another way and do like that :
button_to_click= findElement(By.xpath("//button[#class='btn btn-xs']"));
And it works well , but when i have 3 or 4 elements in this class it just press wrong button.
How can i press exacly this button can someone help me?
Maybe shouold i try something like this?
button_to_click= findElement(By.xpath("//button[#class='btn btn-xs']//button[#title='Skip']"));
Why it don't work only by title? And how can i do that better? Please be patient for newbies.
EDIT 1
I add more code as you want to know what I'm doing. :
This code works well :
driver = new ChromeDriver();
driver.url ="http://mypage.com"
button_to_click= findElement(By.xpath("//button[#class='btn btn-xs']")).Click();
And this code doesn't work :
driver = new ChromeDriver();
driver.url ="http://mypage.com"
button_to_click= findElement(By.xpath("//button[#title='Skip']")).Click();
EDIT 2
I will give you an example page for testing. You just have to download the html file and open it in your browser.Html page file
What we now want to do?
If you run this html file you will see all page.
And now we want to make a Click on exacly this button on screen :
After when you click on this button you will see click counter below : like this :
Have anyone idea how to click it? I try few ways and can't find solution still. Please help.
EDIT 3
I try also : - but it too doesn't work
drive.FindElement(By.XPath("//tr[class='ng-scope']/td[text()='Wylaczenie nadan RDF'] and button[#title='Skip'']]")).Click();
As per your Question, this line of code works :
button_to_click= findElement(By.xpath("//button[#class='btn btn-xs']")).Click();
This line of code does't works :
button_to_click= findElement(By.xpath("//button[#title='Skip']")).Click();
Explanation:
Looking at the HTML DOM it's clear the WebApplication uses a lot of JavaScript & Ajax Calls. Hence are the attributes e.g. ng-repeat, ng-class etc with dynamic values e.g. { "error-row": row.errorMessage }, vm.showError(row.errorMessage) etc. So it will be tough to use these values/attributes to construct an xpath or CSSselector
Using xpath as //button[#title='Skip'] should have worked provided the xpath uniquely identified the specific element of our interest. But as it is not happening I suspect there may be multiple elements matching this xpath where some of them may be disabled/hidden. So, the xpath using the title attribute as Skip FAILED.
Using xpath as //button[#class='btn btn-xs'] works without failure because here we have considered the class attribute which is extensively used within CSSselector as well as within xpath which maps down to querySelector/querySelectorAll. Hence, this option is more reliable and works perfect.
Update :
Though using xpath as //button[#class='btn btn-xs'] works for you without any failure I am not sure why you want to avoid it. About the xpath you mentioned in your comment, as you have got much granular in your search using the <button> tag it seems unnecessary to reference any parent node e.g. tr[text()='Wylaczenie nadan RDF']. Incase xpath as //button[#class='btn btn-xs'] doesn't identifies the element uniquely you can consider to club up the class and title attribute as follows:
button_to_click= findElement(By.xpath("//button[#class='btn btn-xs' and #title='Skip']")).Click();
I'm curious if you have an element higher in the dom with the same attributes and html elements as the XPath that you're attempting to select. Let's get super specific with our XPath and throw in some and conditions. Give this guy a shot:
//button[#ng-show='vm.enableSkip(row)' and #title='Skip' and #class='btn btn-xs']
If you need to add even more identifiers keep throwing them in there. There is nothing wrong with having very concrete XPaths.
It also looks like your button is in a table row. If there is anything unique in the tr element that contains the button you should definitely throw that in the xpath before the button and you wouldn't have to be concerned about it clicking a button in a previous tr, and in doing so you know you wouldn't need anything more than #title='Skip' for your uniqueness for the button portion of the XPath.
For example...
//tr[#attribute='uniqueTRValue']/button[#title='Skip']
I hope I describe my problem/question in a comprehensible way.
I have and html that looks like this:
<div class="class-div">
<label class="class-label">
<span class="class-span">AAAA</span>
</label>
<div class="class-div-a">
<textarea class="class-textarea">
</textarea>
</div>
</div>
<div class="class-div">
<label class="class-label">
<span class="class-span">BBBB</span>
</label>
<div class="class-div-a">
<textarea class="class-textarea">
</textarea>
</div>
</div>
I want the Xpath for the TextArea where the value of the Label is AAAA to populate it with a value in Selenium.
So somelike like this...
wait.Until(ExpectedConditions.ElementIsVisible(
By.XPath("//div[#class='class-div']/label[#class='class-label'][span[#class='class-span' and text()='AAAA']]/following-sibling::div[#class='class-div-a']/textarea[#class='class-textarea']"))).SendKeys(valueTextArea);
Problem could be in this waiter condition, ExpectedConditions.ElementIsVisible
The thing is that your <textarea> is not 'visible' in selenium context, visibility means that element is present in DOM (which is true) and it's size is greater then 0px which could be false for your <textarea> element. In java you would use ExpectedConditions.presenceOfElement() instead of ExpectedConditions.visibilityOfElement(), not sure how it goes in C# but you get the picture.
Try and see if it solves your problem.
Let me quickly rephrase the question to make sure I understand, you need an xpath to find the textbox associated with the label where the text is AAAA.
You'll have to go back up the tree in this case, here are a couple of ways I might do that, although your xpath looks correct:
Using ancestor to be clear about which element you're moving up to (better IMO)
By.XPath("//label/span[text()='AAAA']/ancestor::div[#class='class-div']//textarea");
Or just moving back up the tree with ..
By.XPath("//label/span[text()='AAAA']/../../..//textarea");
If your xpath exists, use asikojevics answer. The C# method is ExpectedConditions.ElementExists(By)
****UPDATE****
Based on your comment of a trailing space after the text value, here is another xpath that should find the textarea in that case, using contains instead of text()=.
By.XPath("//label/span[contains(text(),'AAAA')]/ancestor::div[#class='class-div']//textarea");
I am trying to find an element which is a div inside a div...
here is example of the code:
<div class="col-md-4">
<div style="display: none;" id="multiplier-win" class="label label-success multiplier">2X</div>
<div style="display: block;" id="multiplier-lose" class="label label-danger multiplier">0X</div>
<div style="display: none;" id="multiplier-tie" class="label label-warning multiplier">1X</div>
</div>
I want to find the class="label label-success multiplier" and check if her style="display:none".
How do I write this in c#?
Please help me
thank you!
In your case, the elements have a unique ID. So instead of finding them by class name (which could lead to multiple/inaccurate results), you should use By.Id(...). It is more easy to write by hand than xpath, too.
Let's say your IWebDriver instance is called driver. The code looks like this:
IWebElement element = driver.FindElement(By.Id("multiplier-win"));
String style = element.GetAttribute("style");
...
I don't want to offend you, but you should probably use google before you post here. This is very basic code you will find in multiple tutorials about selenium.
Edit: In case you are looking for multiple elements of a class:
ReadOnlyCollection<IWebElement> elements = driver.FindElements(By.ClassName("..."));
foreach (IWebElement el in elements)
{
...
}
To Find the element:
IWebElement element = driver.FindElement(By.XPath("//div[#class='label label-success multiplier']"));
To check if an element is displayed, this returns a bool (true if displayed, false if not displayed). If you go with philn's element list code, you can throw this line into his foreach statement and it will tell you which ones are displayed.
el.Displayed;
I’m attempting to create a tool, in C#, which gathers and analyses data from a web page/form. There are basically 2 different types of data. Data entered by a user and data created by the system (I don’t have access to).
The data created by the user is kept in fields and the form uses IDs - so GetElementByID is used.
The problem I’m running into is obtaining the data created by the system. It shows on the form, but isn’t associated to an ID. I may be reading/interpreting the HTML incorrectly, but it appears to be a child class (I don’t have much HTML experience). I’m attempting to get the “Date Submitted” data (near the bottom of the code). Sample of the HTML code:
<div class="bottomSpace">
<div class="importfromanotherorder">
<div class="level2Panel" >
<div class="left">
<span id="if error" class="error"></span>
</div>
<div class="right">
Enter Submission ID
<input name="Submission$ID" type="text" id="Submission_ID" class="textbox" />
<input type="submit" name="SumbitButton" value="Import" id="SubmitButton" />
</div>
</div>
</div>
</div>
<div class="bottomSpace">
<div class="detailsinfo">
<div class="level2Panel" >
<div class="left">
<h5>Product ID</h5>
1234567
<h5>Sub ID</h5>
Not available
<h5>Product Type</h5>
Type 1
</div>
<div class="right">
<h5>Order Number</h5>
0987654
<h5>Status</h5>
Ordered
<h5>Date Submitted</h5>
7 17 2012 5 45 09 AM
</div>
</div>
</div>
</div>
Using GetElementsByTagName (searching for “div”) and then using GetAttribute(“className”) (searching for “right”) generates some results, but as there are 2 “right” classes, it’s not working as intended.
I’ve tried searching by className = “detailsinfo”, which I can find, but I’m not sure how I could go about getting down to the “right” class. I tried sibling and children, but the results don't appear to be working. The next possible problem is that it appears the date data is actually text belonging to class “right” and not element “Date Submitted” .
So basically, I'm curious as to how the best approach would be to get the data I'm looking for. Would I need to get all of the class “right” text and then try and extract the date string?
Apologizes if there is too much info or not enough of the required info :) Thanks in advance!
EDIT: Added how GetElementsByTagName is called using C# - per Icarus's comment.
HtmlDocument doc = webBrowser1.Document;
HtmlElementCollection elemColl = doc.GetElementsByTagName("div");
This will do it if the 'right' instance you want is the 2nd. Two approaches given:
The commented-out approach is it's zero based, so uses instance 1.
The second approach is xpath and is therefore one-based so uses instance 2.
private string ReadHTML(string html)
{
System.Xml.XmlDocument doc = new System.Xml.XmlDocument();
doc.LoadXml(html);
System.Xml.XmlElement element = doc.DocumentElement;
//This commented-out approach works and might be preferred if you want to iterate
//over a node set instead of choosing just one node
//string key = "//div[#class='right']";
//System.Xml.XmlNodeList setting = element.SelectNodes(key);
//return setting[1].LastChild.InnerText;
// This xpath appraoch will let you select exactly one node:
string key = "((//div[#class='right'])[2])/child::text()[last()]";
System.Xml.XmlNode setting = element.SelectSingleNode(key);
return setting.InnerText;
}