The .NET HTML parser treats the HtmlTags that reside inside the SELECT tag separately so I cannot just get the attributes for the select and then slice and dice and get the default selected value for the drop in.
I tried to be "elegant" in my solution and use the HTML Agility Pack and a XPath pulled from FireBug but alas, there was no love to be found. I'm not sure what the exact problem is other than me being a total XPath n00b (I normally use an open source Java project to extract XPaths from XML docs) but something was amiss. After wasting several hours trying to get the elegant solution I decided to be like Ike and Tina and just brute force the solution of identifying the default selected value for the drop down lists. I populate the Context of the WebTestRequest with all the values that are extracted and just reference them by element name in the address change POST ala the HIDDEN1$
Here is the extraction code that I wrote to pull the fields that I needed to reference in the Context:
1: void ExtractCustomerDataToContext(object sender, ExtractionEventArgs e) {
2: Dictionary<string, string> customerData = new Dictionary<string, string>();
3: string lastDropDown = null;
4: foreach (HtmlTag tag in e.Response.HtmlDocument.HtmlTags) {
5: string type = tag.GetAttributeValueAsString("type");
6: if (type != null) {
7: lastDropDown = null ;
8: if (type == "text" || type == "checkbox") {
9: if (tag.GetAttributeValueAsString("checked") != null) {
10: if (tag.GetAttributeValueAsString("checked") == "checked") {
11: customerData.Add(tag.GetAttributeValueAsString("name"), "on");
12: } else {
13: customerData.Add(tag.GetAttributeValueAsString("name"), "off");
14: };
15: } else {
16: customerData.Add(tag.GetAttributeValueAsString("name"), tag.GetAttributeValueAsString("value"));
17: };
18: };
19: } else {
20: if (tag.GetAttributeValueAsString("class") != null) {
21: if (tag.GetAttributeValueAsString("class") == "dropDownListDefault") {
22: lastDropDown = tag.GetAttributeValueAsString("name");
23: };
24: } else {
25: if (tag.GetAttributeValueAsString("selected") != null) {
26: if (lastDropDown != null) {
27: customerData.Add(lastDropDown, tag.GetAttributeValueAsString("value"));
28: };
29: };
30: };
31: };
32: };
33: foreach (KeyValuePair<string, string> kvp in customerData) {
34: if (this.Context.ContainsKey("CUSTOMER_UPDATE_DATA." + kvp.Key)) {
35: this.Context.Remove("CUSTOMER_UPDATE_DATA." + kvp.Key);
36: };
37: if (kvp.Value == null) {
38: this.Context.Add("CUSTOMER_UPDATE_DATA." + kvp.Key, "");
39: } else {
40: this.Context.Add("CUSTOMER_UPDATE_DATA." + kvp.Key, kvp.Value);
41: };
42: };
43: }
So, if the previous page HTML has a text field by the name of "txtCustomerAccountNumber" I can simply add that information to the post with:
1: changeAddressRequestBody.FormPostParameters.Add("txtCustomerAccountNumber", this.Context["CUSTOMER_UPDATE_DATA.txtCustomerAccountNumber"].ToString());
As long as the information was displayed via HTML in the prior hit, I should be good to go.
No comments:
Post a Comment