Selenium WebDriver Validating Error Message Text - c#

Please I am trying to validate error message text in a try catch and it is just catching every time. Need assistance with syntax or better way of the validation
string actualResultText = "";
string expectedResultText = "Error: Please Enter User Name";
IWebElement actualResult = webDriver.FindElement(By.XPath("//*[#id='id-7530880b3e6759b']/li/span[contains(text(),'Error: Please Enter User Name')]"));
actualResultText=actualResult.ToString();
if (actualResultText == expectedResultText)
{
result = true;
}
else
{
result = false;
}
Inspect
Please view this inspect against code

I'm working with selenium in python, but the answer might have something similar in C#.
In python, in order to get the text of an element you use:
element = driver.find_element(by, value) # get the element
print(element.text) # get the text of the element
The difference between here and what you are doing (again, if C# has something similar and it works the way I think it is) is using the attribute of the element object text, rather than converting the element object into a string.

Related

Selenium: Get the string out of a email textfield/textbox

I want to get an email string out of an email textbox which was recently entered.
I'm doing automation tests with selenium and to confirm that the correct string was entered into the textbox, I want to recheck it before it goes on to the password textbox.
I saw a lot of examples here but the most are either getText(); (which seems to not work anymore) or getAttribute("Value");.
I debugged it, and the checkText gives always Null.
What im currently having is this code:
public static void SendKeysElement(IWebDriver webDriver)
{
IWebElement Field = webDriver.FindElement(By.XPath(selector));
Field.SendKeys("example#example.com");
string checkText = Field.GetAttribute("Value");
if (checkText != "example#example.com")
{
Console.WriteLine("String is wrong");
}
else
{
ConsoleWriteLine("String is correct");
}
}
Here is the inspect of that textbox, while the email string was entered.
The first thing I notice is, that the entered string in the email textbox is not displayed in the inspect.
The webpage is being written with .NET using a blazor template.
Instead of
.GetAttribute("Value")
try this :
.GetAttribute("value");
Note that, attribute type is case sensitive.

How do I assert the text in Google Search button with Selenium C#?

I tried to write the auto-test with Selenium using C# and asserts the text in Google Search Button.
However the test got failed.
How to do it correctly and what's wrong here?
enter code here
[Test]
public void TestIfButtonNameIsGoogleSearch()
{
Driver.Navigate().GoToUrl("https://www.google.com/?gws_rd=ssl");
var btnSearch = Driver.FindElements(By.Name("btnK"));
if(btnSearch.Count==2)
{
Assert.That(true);
}
string expName = btnSearch.LastOrDefault().Text;
Assert.AreEqual(expName, "Google Search");
}
Use .GetAttribute("value") instead of .Text
you can try the following code. By default inputs are holding the text in 'value' attribute. Normaly its hidden.
Code Example:
var btnSearch = Driver.FindElements(By.Name("btnK"));
var btnFeelingLucky = Driver.FindElements(By.Name("btnI"));
var searchBtnText = btnSearch.GetAttribute("value");
var feelingLuckyBtnText = btnFeelingLucky.GetAttribute("value");
Assert.AreEqual(searchBtnText , "Google Search");
Assert.AreEqual(feelingLuckyBtnText , "I'm Feeling Lucky");
If the 'value' does not return anything or its empty, you can try with:
string btnText = javaScriptExecutor.ExecuteScript("return arguments[0].value", searchBtnText) as string;

Is there any way to do backspace twice to clear a text field using selenium webdriver through C#

I have a text field that contains a 2 digit value by default. I want to clear it before I type a new value. I was using TextSlider.Clear(); but after the latest ChromeDriver update, it's no longer working so I am trying to workaround it using backspace. Currently I am doing two backspaces, one at a time.
TextSlider.SendKeys(Keys.Backspace);
TextSlider.SendKeys(Keys.Backspace);
I also tried DELETE but that's also not working. Is there any way to do this in a single line?
Thank you all,
i have managed to workaround using ctrl A and Delete
TextSlider.SendKeys(Keys.Control + "a");
TextSlider.SendKeys(Keys.Delete);
TextSlider.SendKeys(Keys.Backspace + Keys.Backspace);
First try to fix like how TextSlider.Clear(); is not working. There might me loading issue, SendKeys method will work. Try to add wait for page to load properly.
If still not working then you can use,
TextSlider.Click();
TextSlider.Clear();
But below functionality will definatly work,
TextSlider.SendKeys(Keys.Backspace + Keys.Backspace);
Instead of using Keys.Backspace, ideally to clear a text field you need to induce WebDriverWait for the element to be clickable and you can use either of the following solutions:
Using ElementToBeClickable Method (IWebElement):
new WebDriverWait(driver, TimeSpan.FromSeconds(10)).Until(ExpectedConditions.ElementToBeClickable(TextSlider)).Clear();
Using ElementToBeClickable Method (By):
new WebDriverWait(driver, TimeSpan.FromSeconds(10)).Until(By.CssSelector("css_TextSlider")).Clear();
Another option is to clear the text element by using Javascript. Due to issues occurring in certain parallel testing situations, I stopped relying on the SendKeys function some time ago. Instead, I use these functions now to set a certain text:
private void SetText(IWebElement element, string text, bool clearOldText)
{
// Clear old text if needed
if (clearOldText)
{
LogInfo("Clearing " + element.ToString() + #" from any text.");
SetElementValue(element, "");
}
element.Click();
SetElementValue(element, text);
}
public string SetElementValue(IWebElement element, string value)
{
ScrollToElement(element);
PaintElement(element, "yellow");
var exec = (IJavaScriptExecutor)this;
var script = #"
var el = arguments[0];
el.value = '" + value + #"';
try
{
if (""createEvent"" in document) {
var evt = document.createEvent(""HTMLEvents"");
evt.initEvent(""change"", false, true);
el.dispatchEvent(evt);
}
else
el.fireEvent(""onchange"");
}
catch(err){ return err; }
return ""Javascript executed."";
";
LogInfo("Setting value to '" + value + "' for " + element.ToString());
var result = exec.ExecuteScript(script, element);
Recorder?.AddScreenshot();
return result.ToString();
}
Personally I dislike the hardcoded javascript a bit, but it always did the job reliably. "SetElementValue" is called twice in this code to ensure correct handling of certain events in my tests: it might not be necessary in other cases.

C# String Property and string literal concatenation issue

I am a bit new at C# and I have run into a string concatenation issue. I am hoping someone might be able to give me a hint and help me resolve this. I have searched Google extensively and have spent more than a week on this so any help/advice would be greatly appreciated.
I have created a custom PathEditor for a string property. The property basically allows the user to key in a file to use in the app. If the file typed in is correct, it shows in the property cell as it should. What I am trying to do is output to the property cell an error message if the file typed in does not exist - I check this in my file validator. Here is the string literal issue.
If I use:
return inputFile+"Error_";
this works OK and I get the outpur file123.txtError_ in the property grid cell.
If I use:
return "Error_"+inputFile;
I get only the inputFile without the literal "Error_". Sot he property grid cell shows file123.txt in the property grid cell.
I have checked and inputFile is a string type. Any ideas as to why this is happening?
Also, is there any way to change to font, and/or, color of the message output? I tried to change the background of the property grid cell and I understand that this is not possible to do.
Thank you.
Z
More of the code:
[
Description("Enter or select the wave file. If no extension, or a non .wav extension, is specified, the default extension .wav will be added to the filename."),
GridCategory("Sound"),
Gui.Design.DisplayName ("Input Sound"),
PathEditor.OfdParamsAttribute("Wave files (*.wav)|*.wav", "Select Audio File"),
Editor(typeof(PathEditor), typeof(System.Drawing.Design.UITypeEditor))
]
public string InputWavefile
{
get { return System.IO.Path.GetFileName(inputtWavefile); }
set
{
if (value != inputWavefile) // inputWavefile has been changed
{
// validate the input stringg
_inputWavefile = FileValidation.ValidateFile(value);
// assign validated value
inputWavefile = _inputWavefile;
}
}
}
My guess is that you've got a funky character at the start of inputFile which is confusing things - try looking at it in the debugger using inputFile.ToCharArray() to get an array of characters.
The string concatenation itself should be fine - it's how the value is being interpreted which is the problem, I suspect...
I'm guessing your filename looks something like this, C:\Folder\FileName.txt when you start out.
In your FileValidation.ValidateFile() method you
return "Error_" + InputFileName;
it now looks like this: Error_C:\Folder\FileName.txt.
So, when you run the line below,
get { return System.IO.Path.GetFileName( _inputWavefile ); }
it strips off the path and returns the filename only, FileName.txt.
Even when the filename is not valid, you are still running System.IO.Path.GetFileName() on it.
Assuming this is a PropertyGrid in winforms app. Then it's neither a string concatenation issue, nor PropertyGrid issue, as could be proven by the following snippet. So you need to look elsewhere in your code:
public partial class Form1 : Form {
PropertyGrid pg;
public Form1() {
pg = new PropertyGrid();
pg.Dock = DockStyle.Fill;
this.Controls.Add(pg);
var inputFile = "some fileName.txt";
var obj = new Obj();
obj.One = "Error_" + inputFile;
obj.Two = inputFile + "Error_";
pg.SelectedObject = obj;
}
}
class Obj {
public string One { get; set; }
public string Two { get; set; }
}

control names in a custom validator .NET Client Side Validation

I have a gridview with three columns of textboxes. It can have as many rows as necessary but its usually only about 5 rows. Each row needs to be validated.
I want to create a client side validator that sums 2 of the columns together and compares it with the third column to check that the user has entered the data correctly.
Just in case you are wondering, it's part of the spec that the operator must enter the third column rather than simply summing the two previous columns together in the code behind. This is done to ensure the operator is transcribing the information correctly.
I am trying to use the custom validator in .net to create this client side validation. but I can't find a way to pass to it the names of the three text boxes.
I can give it the target controls name using the ControlToValidate parameter, but how do I pass in the other two control id's ?
I am looking for the 'proper' way to do this, one thought is to create an array in javascript referenced by the controltovalidate's name.
DC
I solved the problem. not an elegant solution but it works.
first I placed the code into a div on the page
<div align="right"><asp:CustomValidator ID="RowValidator" runat="server"
ErrorMessage="Total of #total# does not equal 1st Preference + Ticket"
ControlToValidate="Total" ValidateEmptyText="True"
ClientValidationFunction="CheckRow" SetFocusOnError="True" EnableClientScript="True"
enableViewState="False" Display="Dynamic"></asp:CustomValidator></div>
Then I created a JavaScript function...
function CheckRow(sender,args) {
// get the name of the control to validate
try {
args.IsValid = true;
ctv = sender.controltovalidate;
// get the data from the other controls
nt = document.getElementById(ctv.replace('_Total','_NonTicket'));
t = document.getElementById(ctv.replace('_Total','_Ticket'));
if (nt && t) {
v1 = Number(nt.value);
v2 = Number(t.value);
v3 = Number(args.Value);
if ((v1 + v2) != v3){
msg = GetMessage(sender);
sender.innerHTML = msg.replace("#total#",Number(args.Value));
args.IsValid = false;
return false;
}
}
}
catch (e) {
// something wrong default to server side validation
}
return true;
}
This is called by the custom validator for each row I use the controltovalidate parameter of the sender to get the name
then its a matter of a bit of string manipulation to get the names of the other fields.
Once retrieved you can do what you like, in my case I add and compare. if there is an error the Isvalid flag is cleared and the message is modified to suit.
The getmessage function is required because I alter the message to give a more meaningful error message
/*
get the error message from the validator
store it so it can be retrieved again
this is done because the message is altered
*/
function GetMessage(sender){
msg = window[sender.id+"_msg"];
if (!msg){
msg = sender.innerHTML;
window[sender.id+"_msg"] = msg;
}
return msg;
}
The getmessage function keeps a copy of the original message so if the user makes a mistake more than once the message can be retrieved in its pristine form, other wise the first time we edit a message we overwrite the placeholder (#total#).
DC

Categories

Resources