public Login ClickGetStatus()
{
//IWebElement btnGetStatus = driver.FindElement(By.XPath("//*[contains(#id,'GetStatus')]"));
do
{
buttonName_GetStatus[0] = "abc";
Thread.Sleep(3000);
bool is_displayed =
wrapper.IsElementDisplayed(
driver.FindElement(By.XPath("//*[contains(#id,'GetStatus')]")));
//bool IsElementDisplayed = driver.FindElement(By.XPath("//*[contains(#id,'GetStatus')]")).Displayed;
if (is_displayed)
{
//wrapper.Click(btnExecute);
string getnameofbutton1 =
driver.FindElement(
By.XPath("//*[contains(#id,'GetStatus')]")).GetAttribute("id");
Console.WriteLine("Name of the button is : " + getnameofbutton1);
buttonName_GetStatus = getnameofbutton1.Split('_');
driver.FindElement(
By.XPath("//*[contains(#id,'GetStatus')]")).Click();
}
else
{
Console.WriteLine("Element is not displayed");
}
}
while (buttonName_GetStatus[0] == "GetStatus");
return this;
}
Below is the Logic for the above code
Checks for the button called Get Status
if it finds the button Get Status then clicks on it
i have used contains in the xpath as the element id for that button changes dynamically.
The above code runs fine and clicks on the Get Status button but doesn't come out from the loop when the name of the Get Status button changes to View Result and still searches for Get Status button
If the expected ID of the button after being updated is "ViewResult", then you can update your condition to use that.
while (buttonName_GetStatus[0] != "ViewResult");
This will keep looping round whilst the button does not equal "ViewResult".
Is this the behavior you're trying to achieve?
public Login ClickGetStatus()
{
//IWebElement btnGetStatus = driver.FindElement(By.XPath("//*
[contains(#id,'GetStatus')]"));
do
{
buttonName_GetStatus[0] = "abc";
Thread.Sleep(3000);
var elements = driver.FindElements(By.XPath("//*[contains(#id,'GetStatus')]"));
var is_displayed = elements.Count > 0;
//bool IsElementDisplayed = driver.FindElement(By.XPath("//*[contains(#id,'GetStatus')]")).Displayed;
if (is_displayed)
{
//wrapper.Click(btnExecute);
string getnameofbutton1 =
driver.FindElement(
By.XPath("//*[contains(#id,'GetStatus')]")).GetAttribute("id");
Console.WriteLine("Name of the button is : " + getnameofbutton1);
buttonName_GetStatus = getnameofbutton1.Split('_');
driver.FindElement(
By.XPath("//*[contains(#id,'GetStatus')]")).Click();
}
else
{
Console.WriteLine("Element is not displayed");
}
}
while (buttonName_GetStatus[0] != "ViewResult");
return this;
}
I think problem might be here, especially when you check if isDisplayed == true then this line buttonName_GetStatus = getnameofbutton1.Split('_'); overrides array so that infinitive loop appeared.
Related
To be honest, I have no idea why the variable is being set to null. The object is set, then once I go through the DisplayPromptAsync, it sets the object to null.
I'm not sure what to try as I've never come across this issue.
Here's a gif of the issue. Once I enter into the field and press submit, an object gets reset.
async void OpenContainerItem()
{
// Pause the timer
blnTimerActive = false;
if (SelectedItem != null)
{
if (SelectedItem.intQuanChecked == SelectedItem.intQuantity)
return;
try
{
int intQuantity = 0;
// Ask for quantity
string result = await Application.Current.MainPage.DisplayPromptAsync("Quantity",
"How many " + SelectedItem.objItem.strItemName + " did you count?",
"Okay", cancel: "Cancel",
placeholder: "Quantity",
keyboard: Keyboard.Numeric);
// Check if it's been cancelled
if (result != null)
{
// check if theres nothing entered
if (result == "")
{
// Why tho?
await Application.Current.MainPage.DisplayAlert("Error", "Please enter a quantity.", "Okay");
}
else
{
intQuantity = int.Parse(result);
if (0 > ((SelectedItem.intQuantity - SelectedItem.intQuanChecked) - intQuantity))
{
Application.Current.MainPage.DisplayAlert("Error", "Thats too many items!", "Okay");
Reload();
blnTimerActive = true;
return;
}
modDatabaseUtilities.ContainerItemsPreCheck(SelectedItem.intContainerItemID, intQuantity, strCurrentUser);
Reload();
}
}
}
catch(Exception ex)
{
Application.Current.MainPage.DisplayAlert("Error", "Couldn't process this change. Please try again.", "Okay");
}
}
#ScottUphus - Is SelectedItem bound to a ListView? (If it is bound to anything, you should add that xaml in your question.) If so, then its a common problem: xamarin sets it back to null when the display layout is refreshed. (I'm not sure the exact "rule" for when it happens. In your case, I suspect the modal interaction causes this.)
This is how I solve such issues:
public MyItemType ValidSelectedItem { get; private set; }
public MyItemType SelectedItem
{
get => _SelectedItem;
set {
... your current setter code here ...
// Remember most recent non-null value.
if (value != null)
ValidSelectedItem = value;
}
}
private MyItemType _SelectedItem;
ValidSelectedItem remembers the non-null item, even if xamarin resets the selection back to null. Use it in code that needs that value.
Is there a difference in using "Okay" or "OK" in DisplayPromptAsync ? try to change it in your code.
this is default Page.DisplayPromptAsync Method:
public System.Threading.Tasks.Task<string> DisplayPromptAsync
(
string title,
string message,
string accept = "OK",
string cancel = "Cancel",
string placeholder = default,
int maxLength = -1,
Xamarin.Forms.Keyboard keyboard = default,
string initialValue = ""
);
I have a list of records with for example status, department, amount, title and some buttons.
If I wanted to assert for example the title I used the following code:
private IWebElement GetTitleElement(int actionRowNumber)
{
var xpath = $"//tr[#id = 'ctl00_ctl00_CPH_CPH_ActionsOverviewControl1_RadGridActions_ctl00__{actionRowNumber}']/td[9]";
return BrowserFactory.Driver.FindElement(By.XPath(xpath));
}
I am doing the same for type, status, department
And then I used a try catch method to go through each record untill I found the desired record in the system:
public void CheckActionxxx(ActionTypes type, Enum.Departments departments, Enum.ActionStatus actionstatus, string title)
{
Wait();
var actiontype = type;
try
{
for (var i = 0; i <= 4; i++)
{
if (GetTitleElement(i).Text == title && GetActionTypeElement(i).Text == actiontype.ToString())
{
Assert.AreEqual(type.ToString(), GetActionTypeElement(i).Text);
Assert.AreEqual(actionstatus.ToString(), GetActionStatusElement(i).Text);
Assert.AreEqual(departments == Enum.Departments.None ? " " : departments.ToString(),
GetActionDepartmentElement(i).Text);
return;
}
}
throw new NoSuchElementException();
}
catch (NoSuchElementException)
{
throw new NoSuchElementException($"Not found with'{title}'");
}
}
Because the id’s only had a difference in numbers (e.g. 0,1,2) I was able to use integer
Department:
//[#id="ctl00_ctl00_CPH_CPH_ActionsOverviewControl1_RadGridActions_ctl00__0"]/td[5]
//[#id="ctl00_ctl00_CPH_CPH_ActionsOverviewControl1_RadGridActions_ctl00__1"]/td[5]
//*[#id="ctl00_ctl00_CPH_CPH_ActionsOverviewControl1_RadGridActions_ctl00__2"]/td[5]
Status:
//[#id="ctl00_ctl00_CPH_CPH_ActionsOverviewControl1_RadGridActions_ctl00__0"]/td[2]
//[#id="ctl00_ctl00_CPH_CPH_ActionsOverviewControl1_RadGridActions_ctl00__1"]/td[2]
//*[#id="ctl00_ctl00_CPH_CPH_ActionsOverviewControl1_RadGridActions_ctl00__2"]/td[2]
Title:
//[#id="ctl00_ctl00_CPH_CPH_ActionsOverviewControl1_RadGridActions_ctl00__0"]/td[9]
//[#id="ctl00_ctl00_CPH_CPH_ActionsOverviewControl1_RadGridActions_ctl00__1"]/td[9]
//*[#id="ctl00_ctl00_CPH_CPH_ActionsOverviewControl1_RadGridActions_ctl00__2"]/td[9]
Now I want to use a try catch that finds a button based on the same way of working but the id of this button is as follow:
//[#id="ctl00_ctl00_CPH_CPH_ActionsOverviewControl1_RadGridActions_ctl00_ctl04_ButtonClose"]
//[#id="ctl00_ctl00_CPH_CPH_ActionsOverviewControl1_RadGridActions_ctl00_ctl06_ButtonClose"]
//[#id="ctl00_ctl00_CPH_CPH_ActionsOverviewControl1_RadGridActions_ctl00_ctl08_ButtonClose"]
//[#id="ctl00_ctl00_CPH_CPH_ActionsOverviewControl1_RadGridActions_ctl00_ctl10_ButtonClose"]
//*[#id="ctl00_ctl00_CPH_CPH_ActionsOverviewControl1_RadGridActions_ctl00_ctl12_ButtonClose"]
As you can see it starts at ctl04 and continues in steps of two.
I cannot figure out how to design my private webelement. I tried:
private IWebElement GetActionCloseButtonElement(int actionRowNumber)
{
var xpath = $"//tr[#id = 'ctl00_ctl00_CPH_CPH_ActionsOverviewControl1_RadGridActions_ctl00_{actionRowNumber}_ButtonClose']";
return BrowserFactory.Driver.FindElement(By.XPath(xpath));
}
But that doesnt work.
Something like this should work.
actionRowNumber should be 04, 06, 08, 10, 12 as from the xpath.
private IWebElement GetActionCloseButtonElement(int actionRowNumber)
{
return BrowserFactory.Driver.FindElement(By.Xpath("//tr[#id = 'ctl00_ctl00_CPH_CPH_ActionsOverviewControl1_RadGridActions_ctl00_ctl"+ actionRowNumber +"_ButtonClose']"));
}
I am checking for duplicates and it finds them and the If(isDuplicate) all works fine.
But the code continues and does all the submit because I am not telling it to stop.
How would I do this ? to stop and throw the error panel which it does but not submit?
_db.tbl_Localities.InsertOnSubmit(locality);
bool isDuplicate = _db.tbl_Localities
.Any(x => x.Locality == txt_Locality.Text);
if (isDuplicate)
{
pnl_Message.Visible = true;
lbl_message.Text = " Duplicate entry!";
txt_Locality.Text = "";
}
// Save
// ====
_db.SubmitChanges();
You should handle else part of condition, or raise an exception if it's unexpected situation for your program:
_db.tbl_Localities.InsertOnSubmit(locality);
bool isDuplicate = _db.tbl_Localities
.Any(x => x.Locality == txt_Locality.Text);
if (isDuplicate)
{
pnl_Message.Visible = true;
lbl_message.Text = " Duplicate entry!";
txt_Locality.Text = "";
}
else
{
// Save
// ====
_db.SubmitChanges();
}
Use return; in the if statement.
I have a combobox with two items. I also have a button that opens a new form when one of these items are selected. However if none of the items are selected there is an exception(nullpointer). I have tried (to no avail) to catch this exception and show a mbox that prompts the user to choose one of the items.
Here is the code for the button click even:
if (labelGrid.Text == "Member" && cbTable.SelectedItem.ToString().Equals("Workout"))
{
string name;
string ss;
foreach (DataGridViewRow item in this.dtGrid1.SelectedRows)
{
ss = dtGrid1.CurrentCell.Value.ToString();
name = dtGrid1.SelectedCells[1].Value.ToString();
BookMemberWorkout bmw = new BookMemberWorkout(ss, name);
bmw.Label2.Text = ss;
bmw.Label1.Text = name;
bmw.ShowDialog();
}
}
You are not supposed to use exceptions for flow control in non-exceptional cases. The case that the user didn't select anything is surely not exceptional.
The correct approach would be a simple null check:
if(cbTable.SelectedItem == null)
{
// Show message box
}
else
{
// Your current code
}
Why your exception handling code isn't working is impossible to answer, because you didn't include it in your question.
I think the problem is in the line:
ss = dtGrid1.CurrentCell.Value.ToString();
You can't be sure the value is not null, so you should check it before calling the .ToString().
Instead of using a message box you could use a RequiredValidator to perform javascript validation, avoiding a useless postback.
From performance and readability point-of-view, I'd recommend checking for selected value in the combo box rather than catching an exception, like this
if(cbTable.SelectedItem == null)
{
MessageBox.Show("Please select a value in the combo box.");
return;
}
if (labelGrid.Text == "Member" && cbTable.SelectedItem.ToString().Equals("Workout"))
{
string name;
string ss;
foreach (DataGridViewRow item in this.dtGrid1.SelectedRows)
{
ss = dtGrid1.CurrentCell.Value.ToString();
name = dtGrid1.SelectedCells[1].Value.ToString();
BookMemberWorkout bmw = new BookMemberWorkout(ss, name);
bmw.Label2.Text = ss;
bmw.Label1.Text = name;
bmw.ShowDialog();
}
}
However to answer your specific query, you can catch NullReferenceException like this:
try{
if (labelGrid.Text == "Member" && cbTable.SelectedItem.ToString().Equals("Workout"))
{
string name;
string ss;
foreach (DataGridViewRow item in this.dtGrid1.SelectedRows)
{
ss = dtGrid1.CurrentCell.Value.ToString();
name = dtGrid1.SelectedCells[1].Value.ToString();
BookMemberWorkout bmw = new BookMemberWorkout(ss, name);
bmw.Label2.Text = ss;
bmw.Label1.Text = name;
bmw.ShowDialog();
}
}
}
catch(NullReferenceException ex)
{
MessageBox.Show("Please select a value in the combo box.");
}
I have the following JavaScript function. I have two textboxes, two hiddenfields and two labels. and a button. On the click of a button I am calling this function.
On typing value in the textbox, It shows an autoCompleteList. On picking a value from this, it fetches the value from DB and fills the corresponding label. Also, at the same time it stores the corresponding selected value in hiddenfield.
Whenever one changes the value in textbox and without selecting the value from autoPopulated list, It must show the alert.
The function is working fine, If I fill a single textbox, but when I fill both, It goes to the Point A, instead of showing the alert of Point B
function ConfirmBox()
{
var txtBoxValue = document.getElementById("<%= txtFromPartNumber.ClientID %>").value;
var txtBoxValue1 = document.getElementById("<%= txtToPartNumber.ClientID %>").value;
var release = document.getElementById("<%= lblFromPartNumber.ClientID %>").innerText;
var release1 = document.getElementById("<%= lblToPartNumber.ClientID %>").innerText;
var hdnFromValueID = "<%= hdnFromReleaseNumber.ClientID %>";
var hdnToValueID = "<%= hdnToReleaseNumber.ClientID %>";
if ((txtBoxValue && txtBoxValue.trim() != "" && release))
{
if (document.getElementById(hdnFromValueID).value.trim() == txtBoxValue.trim())
{
if ((txtBoxValue1 && txtBoxValue1.trim() != "" && release1))
{
if (document.getElementById(hdnToValueID).value.trim() == txtBoxValue1.trim())
{
return true; //Point A
}
else
{// Point B
//alert("To Part no. has been changed. Please enter it again.");
var msg = document.getElementById("alertMessage");
msg.innerHTML = "To Part no. has been changed. Please enter it again.";
var myExtender = $find("ctl00_ContentPlaceHolder1_ModalPopupExtenderAlert");
myExtender.show();
document.getElementById("<%= txtToPartNumber.ClientID %>").focus();
return false;
}
}
else
{
//window.alert("Please choose a Valid To Part number");
var msg = document.getElementById("alertMessage");
msg.innerHTML = "Please choose a Valid To Part number.";
var myExtender = $find("ctl00_ContentPlaceHolder1_ModalPopupExtenderAlert");
myExtender.show();
return false;
}
}
else
{
//alert("From Part no. has been changed.Please enter it again.");
var msg = document.getElementById("alertMessage");
msg.innerHTML = "From Part no. has been changed.Please enter it again.";
var myExtender = $find("ctl00_ContentPlaceHolder1_ModalPopupExtenderAlert");
myExtender.show();
document.getElementById("<%= txtFromPartNumber.ClientID %>").focus();
return false;
}
}
else
{
//window.alert("Please choose a Valid From Part number");
var msg = document.getElementById("alertMessage");
msg.innerHTML = "Please choose a Valid From Part Number.";
var myExtender = $find("ctl00_ContentPlaceHolder1_ModalPopupExtenderAlert");
myExtender.show();
return false;
}
}