Can I get the locator string from a By? - c#

At the moment, I'm storing references to page elements as Bys:
public By showAllCheckbox = By.Id("show-all");
public By addArticleButton = By.CssSelector("a[id='add-article-btn']");
public By exampleEventCategoryEntityPickerPlusButton = By.XPath("//*[#id='j1_1']/i");
public By exampleEventReasonEntityPickerEntity = By.CssSelector("a[id='7603_anchor']");
Using selenium (or some other witchcraft) is it possible to get that selector string back out of the By? For example, for the add article button above I would want to get "a[id='add-article-btn']".
Thanks!

I think you can do it as follows, You can use toString()
By addArtclBtn = By.CssSelector("a[id='add-article-btn']");
String selector = addArtclBtn.toString();
selector value will be something like this "By.cssSelector: a[id='add-article-btn']", Then what you can do is, just spliit the value by ": ".
String[] splittedValues = selector.split(": ");
String value = splittedValues[1];

Related

How can I simplify the setting up of an array with a simple local method

My code sets icon svgs like this:
Current.Resources["HomePageIcon5"] = (new[] {
"resource://Japanese.Resources.5_Light.svg",
"resource://Japanese.Resources.5_Gray.svg",
"resource://Japanese.Resources.5_Dark.svg" })[thc];
It does the same for many more icons and the same string
"resource://Japanese.Resources."
Appears many times.
Is there a way I could create a local method that could do this for me? What I am looking for is something I could call like this:
Current.Resources["HomePageIcon5"] = X("5_Light","5_Gray","5_Dark");
something like:
private static readonly _resourcesPath = "resource://Japanese.Resources.";
public void FillResource(string key, string value, int idx)
{
var content = new[]
{
_resourcesPath + value + "_Light.svg",
_resourcesPath + value + "_Gray.svg",
_resourcesPath + value + "_Dark.svg"
}
Current.Resources[key] = content[idx];
}
and use it like:
FillResource("HomePageIcon5", "5", thc);
The exact implementation for your request will be the following:
public string[] GetFormattedResources(params string[] strings)
{
const string STRING_FORMAT = "resource://Japanese.Resources.{0}.svg";
return strings.Select(str => string.Format(STRING_FORMAT, str)).ToArray();
}
This function uses the params keyword for grouping the strings and LINQ functions to handle the collection easily. (For example: Select)
The call will be as follows:
Current.Resources["HomePageIcon5"] = GetFormattedResources("5_Light","5_Gray","5_Dark");

How to Get Custom Field value acumatica

I'm new in developing acumatica I am stuck at getting the value of a custom TextEdit field that I created. I can get all of the built-in field value through this code
InventoryItem items = (InventoryItem)Base.Item.Cache.Current;
but I cannot get the one that I have created at acumatica customization
here is the field I want to get
https://i.stack.imgur.com/gPln4.png
I already tried
InventoryItem items = (InventoryItem)Base.ItemSettings.Cache.Current;
var shortdesc = items.UsrShortDescription;
But it's not working and does not show the value inside the textbox
thank you in advance for helping
InventoryItem items = (InventoryItem)Base.ItemSettings.Current;
var itemExt = PXCache<InventoryItem>.GetExtension<InventoryItemExt>(items);
var shortdesc = itemExt.UsrShortDescription;
Vardan showed one way, for completeness of picture want to show another as well:
InventoryItem items = (InventoryItem)Base.ItemSettings.Current;
var itemExt = items.GetExtension<InventoryItemExt>();
This is an example of getting value from a non-extension field. I did not use extension DAC to add the Gift card field to the store setup screen.
In a method I need to get the value of that field. I should check whether the order contains Gift card item or not.
public static bool GiftcardName(OrderModel orders, BZWoocommerceStore store)
{
// "ZGift CArd W" => "giftcard"
string wooCommName = string.Empty;
string wooCommNameNoSpases = string.Empty;
bool containsGiftcardName = false;
bool isGiftcard = false;
foreach (OrderLineModel line in orders.LineItems)
{
string gNameInAcumatica = store.GiftcardIdentifier;
string gNameInAcumaticaWithoutSpaces = gNameInAcumatica.Replace(" ", "");
wooCommName = line.Name; //pattern
wooCommNameNoSpases = wooCommName.Replace(" ", "");
//wooCommNameNoSpases = new string(wooCommName.ToCharArray()
// .Where(c => !Char.IsWhiteSpace(c))
// .ToArray());
//woCommNameNoUperCase= wooCommNameNoSpases.ToLower();
//isGiftcardName= woCommNameNoUperCase.Contains(gName);
//containsGiftcardName = wooCommNameNoSpases.Contains(gName);
containsGiftcardName = Regex.IsMatch(wooCommNameNoSpases, gNameInAcumaticaWithoutSpaces, RegexOptions.IgnoreCase);
if(containsGiftcardName)
{
isGiftcard = true;
}
}
return isGiftcard;
}
So, when I call this method I give to that 2 arguments, orders and store.
The store argument was created in this way.
public PXSelect<BZWoocommerceOrder> Order;
In an action method I wrote this.
string storeCode = this.Order.Current.StoreCode;
BZWoocommerceStore store = PXSelect<BZWoocommerceStore, Where<BZWoocommerceStore.storeCode, Equal<Required<BZWoocommerceStore.storeCode>>>>.Select(this, storeCode);
My GiftcardName() method sees the value of original field. Writing "Original" I mean that you do not use any technique like this one.
BZSOOrderExt rowExt = sender.GetExtension<BZSOOrderExt>(row);

Possible to set values of RegEx?

I'm just wondering if its possible to set my "set of values" to put to RegEx (Or any other methods if there is)...?
Here's what I need to do...
string myString = "Hello<<Prefix>> <<surname>>!!";
My PROBLEM:
I need to replace those strings with "<<....>>" to a value in my database.
I'm thinking of getting all those "<<....>>" and put it in a List but if you have other simpler/easier way, please help me.
Thank you in advance!
It sounds more like you need to use String.Format method. Given:
public class User
{
public string Prefix {get; set;}
public string Surname {get; set;}
}
The output should be constructed like:
var message = String.Format("Hello {0} {1}!!", user.Prefix, user.Surname);
A keyword you might want to search on is templating. One way to do it would be something like this:
var dict = new Dictionary<string,string>()
// Populate the dictionary with your key values
dict.Add("PREFIX", "Mr");
dict.Add("SURNAME", "Prescott");
string myString = "Hello<<PREFIX>> <<SURNAME>>!!";
foreach(item in dict)
{
myString = myString.Replace("<<" + item.Key + ">>", item.Value);
}
Note this is a bit naive, it will loop through an entire dictionary you load even if there is only one element to replace.

Assign the entire QueryString to a String?

I've passed a really long Query String from one page to another in my Windows Phone 8 project.
I need to pass these parameters from the new page to another page but don't want to reconstruct he entire QueryString.
Is there a way to assign the entire QueryString to a new String?
Something like
String newQuery = NavigationContext.QueryString.ToString();
I need to pass these parameters from the new page to another page but
don't want to reconstruct the entire QueryString
Why not? This is programming: do all the work in one place so you don't have to do it again later. Let's use an extension method to do this.
Silverlight
Place this code in a static class...
public string ToQueryString(this IDictionary dict)
{
string querystring = "";
foreach(string key in dict.AllKeys)
{
querystring += key + "=" + dict[key] + "&";
}
return querystring;
}
Use it like this...
string QueryString = NavigationContext.QueryString.ToQueryString();
ASP.NET
When I originally read this question, I thought it was for ASP.NET, not Silverlight. I'll leave the ASP.NET answer here in case someone stumbles across it looking for how to do it in ASP.NET.
public string ToQueryString(this NameValueCollection qs)
{
string querystring = "";
foreach(string key in qs.AllKeys)
{
querystring += key + "=" + qs[key] + "&";
}
return querystring;
}
Use it like this...
string QueryString = Request.QueryString.ToQueryString();
There is something that already exists for ASP.NET. But I feel it's important to demonstrate that you can do all the work once somewhere. Then not have to do it again. If you want to use a built-in way, something like this would work, using the Query property of the Uri class.
string QueryString = System.Web.HttpContext.Current.Request.Url.Query;
Here's a way that may be a little simpler...
You could project the results into a format of your choosing. Here's a simple example below.
I've used an IDictionary<string,string> as it is the underlying type for NavigationContext.QueryString
var test = new Dictionary<String,String>();
test.Add("1", "one");
test.Add("2", "two");
test.Add("3", "three");
// Choose any string format you wish and project to array
var newArray = test.Select(item => item.Key + ":" + item.Value).ToArray();
// Join on any separator
string output = String.Join(",", newArray);
This still means that you have to interpret the result later (according to the format you chose). Here you'll get a format like
"1:one,2:two,3:three"
If you've sent it as a querystring just pull it back out on the OnNavigatedTo() Method and then you can store the query in the page until you move on?.
string newQuery;
protected override void OnNavigatedTo(NavigationEventArgs e)
{
newQuery = NavigationContext.QueryString["queryName"];
}
Try this:
public string GetQueryString()
{
IDictionary<String, String> NavigationContextData = NavigationContext.QueryString;
string data = "/Pagename.xaml?";
foreach (var item in NavigationContextData)
{
data += item.Key + "=" + item.Value + "&";
}
data = data.Substring(0, data.Length - 1);
return data;
}
If it's in your OnNavigatedTo() event, you can use a quick, easy two-liner. This can be condensed to a single line or expanded to check for the existence of the ? character. If you know that there are always parameters passed, the check is unnecessary and these two lines work fine:
string QStr = e.Uri.ToString();
string ParmStr = QStr.Substring(QStr.IndexOf('?') + 1);
You can also condense it into a single line:
string ParmStr = e.Uri.ToString().Substring(e.Uri.ToString().IndexOf('?') + 1);

C# Array Conversion

Any help here as I'm a C# noob. The following code works fine and returns 1 string ViewState2. I'd like it to return an array of ViewState2 and EventValidation2 so I can manipulate it later on. How would I convert the code below to return an array?
public string get_status(string local_fname)
{
var dts_doc = new HtmlAgilityPack.HtmlDocument();
dts_doc.Load(local_fname);
//Pull the values
var ViewState = dts_doc.DocumentNode.SelectSingleNode("/html[1]/body[1]/div[1]/input[4]/#value[1]");
var EventValidation = dts_doc.DocumentNode.SelectSingleNode("/html[1]/body[1]/div[2]/input[1]/#value[1]");
string ViewState2 = ViewState.Attributes[3].Value;
string EventValidation2 = EventValidation.Attributes[3].Value;
//Display the values
//System.Console.WriteLine(ViewState.Attributes[3].Value);
//System.Console.WriteLine(EventValidation.Attributes[3].Value);
//System.Console.ReadKey();
return ViewState2;
}
Don't use an array, but a class. Doing this, you don't have to remember what each element means.
public class Status
{
public string ViewState {get; set;}
public string EventValidation {get; set;}
}
using System;
using HtmlAgilityPack;
[...]
public Status GetStatus(string localFileName)
{
var dtsDoc = new HtmlDocument();
dtsDoc.Load(localFileName);
//Pull the values
var viewStateNode = dtsDoc.DocumentNode.SelectSingleNode("/html[1]/body[1]/div[1]/input[4]/#value[1]");
var eventValidationNode = dtsDoc.DocumentNode.SelectSingleNode("/html[1]/body[1]/div[2]/input[1]/#value[1]");
string viewState = viewStateNode.Attributes[3].Value;
string eventValidation = eventValidationNode.Attributes[3].Value;
//Display the values
//Console.WriteLine(viewState);
//Console.WriteLine(eventValidation);
//Console.ReadKey();
return new Status
{
ViewState = viewState,
EventValidation = eventValidation
}
}
Also, you should read up on coding guidelines and naming conventions in the C# language, also the using statement might be interesting. I have corrected some "mistakes", but probably didn't catch all. Also, I have renamed a couple of variables, to make their content clearer. You also might want to look into using the var keyword only in a loop, while using LINQ (or anomynous types in general) or with really long class names. Written out type names can increase readability quite a lot.
If you really want an array with ViewState2 and EventValidation2 in it, you can make the following changes:
// Notice: return value of string[] instead of string
public string[] get_status(string local_frame);
And:
// Notice: returning an array
return new string[] { ViewState2, EventValidation2 };
That said, this is really the "quick and dirty" approach, and is not really appropriate if you're going to want this code to be maintainable (when's the last time you read documentation on a function that "returns an array of length 2, with a string representing X as the first element and another string representing Y as the second"?).
Femaref's right; the correct thing to do would be to encapsulate the information you want returned in its own type.
Assuming you answer yes to this question (although I'd recommend a different approach, see below) this will do what you're asking:
public String[] get_status(string local_fname)
{
var dts_doc = new HtmlAgilityPack.HtmlDocument();
dts_doc.Load(local_fname);
//Pull the values
var ViewState = dts_doc.DocumentNode.SelectSingleNode("/html[1]/body[1]/div[1]/input[4]/#value[1]");
var EventValidation = dts_doc.DocumentNode.SelectSingleNode("/html[1]/body[1]/div[2]/input[1]/#value[1]");
string ViewState2 = ViewState.Attributes[3].Value;
string EventValidation2 = EventValidation.Attributes[3].Value;
String[] retValues = new String[2];
retValues[0] = ViewState2;
retValues[1] = EventValidation2;
return retValues;
//Display the values
//System.Console.WriteLine(ViewState.Attributes[3].Value);
//System.Console.WriteLine(EventValidation.Attributes[3].Value);
//System.Console.ReadKey();
return ViewState2;
}
That said, I would follow the approach afte the line.
I'd write a class that has the data members you want:
public class DataClass
{
public string ViewState { get; set; }
public string EventValidation { get; set; }
}
Then I'd modify the method to return an instance of your data class.
public DataClass get_status(string local_fname)
{
var dts_doc = new HtmlAgilityPack.HtmlDocument();
dts_doc.Load(local_fname);
//Pull the values
var ViewState = dts_doc.DocumentNode.SelectSingleNode("/html[1]/body[1]/div[1]/input[4]/#value[1]");
var EventValidation = dts_doc.DocumentNode.SelectSingleNode("/html[1]/body[1]/div[2]/input[1]/#value[1]");
var dc = new DataClass();
dc.ViewState = ViewState.Attributes[3].Value;
dc.EventValidation = EventValidation.Attributes[3].Value;
return dc;
}
string[] array = new string[2];
array[0] = ViewState2;
array[1] = EventValidation2;
return array;
But it seems to trivial as answer. Please Does it solve your problem? If no, can you specify better the question please?

Categories