"ChromeOptions.AddUserProfilePreference" updating in a wrong format in Selenium C# - c#

I wanted to update Chrome Profile preferences in Selenium C# to make a popup disappear by adding following line as part of Chrome Options.
string url = "https://google.com";
string envName = "xyz.qa";
ChromeOptions.AddUserProfilePreference("protocol_handler.allowed_origin_protocol_pairs." + url + "." + envName, true);
However the above line is resulting in updating chrome profile preference file in a wrong format i.e., when it encounters .(dot) in preference name it is not getting suppressed.
Expected:
"protocol_handler":{"allowed_origin_protocol_pairs":{"https://google.com":{"xyz.qa":true}}}
Actual:
"protocol_handler":{"allowed_origin_protocol_pairs":{"https://google" {"com":{"xyz" {"qa":true}}}}}
Second approach:
string jsonValue = "{ " + url + ":{ " + envName + ":true} }";
var obj = JObject.Parse(jsonValue);
ChromeOptions.AddUserProfilePreference("protocol_handler.allowed_origin_protocol_pairs", obj);
Expected: "protocol_handler":{"allowed_origin_protocol_pairs":{"https://google.com":{"xyz.qa":true}}}
Actual: "protocol_handler":{"allowed_origin_protocol_pairs":{"https://google.com" :{"xyz.qa":[] }}}
Everything looks good except the value true, it is getting replaced with [].
I tried different ways to correct the format but not able to get it corrected. Please suggest how do I update the preference file in expected format.

Finally, able to figure out how to update the ChromeProfile preferences when the url or app name contains . (dot). Hope this helps someone to handle the Chrome Security popup through code.
var first = new Dictionary<string, object> { };
var second = new Dictionary<string, object> { };
options.prefs = new Dictionary<string, object> { };
first.Add("<<ApplicationName>>." + "<<Environment>>", false);
second.Add("<<ApplicationURL>>", first);
options.AddUserProfilePreference("protocol_handler.allowed_origin_protocol_pairs", second);

Related

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.

Interaction between Xamarin & Facebook

I'm trying to connect to facebook using my xamarin app, and then posting thing.
I got this working so far, however when I use the Map layout for my custom graph story, I cannot attach the coordinates I need to use.
I'm currently using a dictionary:
Dictionary<string, string> results = new Dictionary<string, string>
{
{"route", DictionaryToJson(routeObject)},
{"location_start", DictionaryToJson(point1)},
{"distance", "5.2"},
{"duration", "01:05:36"},
{"maxspeed", "12.4"},
{"message", "Blargh"},
};
var newRequest = new OAuth2Request("POST",
new Uri("https://graph.facebook.com/me/tracker:obj"),
results, Account);
DictionaryToJson:
private string DictionaryToJson(Dictionary<string, string> dict)
{
var entries = dict.Select(d =>
string.Format("\"{0}\": \"{1}\"", d.Key, string.Join(",", d.Value)));
return "{" + string.Join(",", entries) + "}";
}
This works fine for all objects that can be converted to a string, however I cannot use this for the GeoPoint collection I need to pass to it, for it to draw the route.
Anyone knows how this can be done? I've been trying to get this working for an entire day by now, and no progress.

Web.config issue - The given key was not present in the dictionary

I have ran into a really annoying issue which gives me this error: "The given key was not present in the dictionary."
What I don't get is that it worked perfectly as intedded last friday and the days before that. I have debugged, checked if the webservice files were intact etc. It all fits.
All I did last friday was running a script which ran trough all of the items in my list which contains the article pages and edited their creation date. I don't know if that could have changed something, but that's the only thing I can recall.
ASPX.CS
protected void Page_Load(object sender, EventArgs e)
{
var listId = Request.QueryString["ListID"];
var itemId = Request.QueryString["ItemID"];
try
{
var spList = SPContext.Current.Web.Lists[new Guid(listId)];
var item = spList.GetItemById(int.Parse(itemId));
var image = (ImageFieldValue)item["PublishingPageImage"];
var contentType = (string)item["ContentType"];
var pageLayout = (string) item["PublishingPageLayout"];
var news = new News
{
Title = (string)item["Title"],
NewsId = item.UniqueId,
Content = (string)item["PublishingPageContent"],
ArticleDate = item["ArticleStartDate"] == null ? DateTime.Now : (DateTime)item["ArticleStartDate"],
PageName = item.File.Name,
Author = new SPFieldUserValue(SPContext.Current.Web, (string)item["Author"]).User.LoginName,
IsArticle = contentType.Contains("Article"),
PageLayout = GetLayout(pageLayout),
Image = GetImage(image)
};
// Jumps to the WSInstance class.
WSInstance.InternetInstance().PublishNews(news); // This line throws the exception.
lblMessage.Text = "News '<i>" + news.Title + "</i>' have been published succesfully to the Internet site.";
}
catch (Exception ex)
{
EventLogger.LogError("Error occured while publishing news: " + ex.Message + "\n" + ex.StackTrace, this);
}
}
WSINSTANCE
public static WSIntegration InternetInstance(SPSite spSite)
{
// Jumps to the Configuration class.
var url = Configuration.GetConfigurationValue("Progressive.WS.Internet", spSite);
...
return new WSIntegration
{
Credentials = new NetworkCredential(username, password, domain),
Url = url
};
}
public static WSIntegration InternetInstance()
{
return InternetInstance(SPContext.Current.Site);
}
CONFIGURATION
public static class Configuration
{
public static string GetConfigurationValue(string key, SPSite site)
{
var name = site.WebApplication.IisSettings[site.Zone].ServerComment; // This is where it fails and throws the error: "The given key was not present in the dictionary."
var value = "";
SPSecurity.RunWithElevatedPrivileges(() => { value = WebConfigurationManager.OpenWebConfiguration("/", name).AppSettings.Settings[key].Value; });
return value;
}
}
The section which it gets hold of the data from the web.config file.
<appSettings><add key="Progressive.WS.Internet" value="http://shpt02/_layouts/DR/WSIntegration.asmx" /> // This is the key value it cannot find.
<add key="Progressive.WS.Internet.Username" value="user" />
<add key="Progressive.WS.Internet.Password" value="password" />
<add key="Progressive.WS.Internet.Domain" value="domain" /></appSettings>
The error says that it can't find the site's Zone in the IisSettings dictionary. You should check both the value of the Zone property and the contents of the IisSettings dictionary. They may not contain the values you expect, since you access the IisSettings outside RunWithElevatedPrivileges, ie. with the end user's access rights.
In any case storing application settings in web.config is not the best option in SharePoint, as a web application hosts many site collections and sites. Modifying it causes all the sites to restart and recompile - not a good end user experience!
Check the Application Settings Manager section in the Sharepoint 2010 Guidance for an alternative way that stores settings in the appropriate site's property bag.
Saw Steve's comment and agree that any pointers to where the error is occuring would be good. Is this Silverlight (or WPF)? If so, it can be a styling name you used in your XAML is not present in the dictionary. Check names carefully and determine if there is an issue here.
Both are possible locations for the issue. Naming issues are often missed as you run through code.

Accessing the Sharepoint Lists Web Service from .NET

I have an InfoPath form with custom submit code to update a Sharepoint list by calling the Sharepoint Lists web service. The code runs without any exceptions, and I was able to set breakpoints to make sure that the variables contain the correct values before being sent to the web service. The values never get added to the Sharepoint list, though. Here is my code:
[InfoPathEventHandler(MatchPath = "Submit", EventType = InfoPathEventType.OnClick)]
public void Submit_OnClick(DocActionEvent e)
{
ListsService.Lists listService = new Risk_Form.ListsService.Lists();
listService.Credentials = System.Net.CredentialCache.DefaultCredentials;
string riskID = thisXDocument.DOM.selectSingleNode("//my:myFields/my:RiskID").text;
string headline = thisXDocument.DOM.selectSingleNode("//my:myFields/my:RiskHeadline").text;
XmlDocument doc = new XmlDocument();
XmlElement batch = doc.CreateElement("Batch");
batch.SetAttribute("OnError", "Continue");
batch.SetAttribute("ListVersion", "1");
batch.InnerXml =
"<Method ID='" + riskID + "' Cmd='New'>" +
"<Field Name='RiskID'>" + riskID + "</Field>" +
"<Field Name='Headline'>" + headline + "</Field>" +
"</Method>";
try
{
// Update list using the list's GUID
listService.UpdateListItems("2F6CA5F4-D78A-4716-B111-507917CF89E4", batch);
}
catch(Exception ex)
{
thisXDocument.DOM.selectSingleNode("//my:myFields/my:RiskStatement").text = ex.Message;
}
}
Two things:
You might also need the default View ID in your batch when calling UpdateListItems().
Instead of hardcoding the list guid, you can obtain it programatically by calling listService.GetListAndView().
Here is some code to demonstrate both items:
System.Xml.XmlNode ndListView = listService.GetListAndView(DISPLAYNAMEOFLIST, "");
string listGuid = ndListView.ChildNodes[0].Attributes["Name"].Value;
string listView = ndListView.ChildNodes[1].Attributes["Name"].Value;
batch.SetAttribute("ViewName", listView);
You can then just call UpdateListItems() with listGuid and batch.
Ok, I finally figured this stupid bug out. There was a list on the root Sharepoint site with the same display name as the list I was trying to access on my subsite. Even though my service reference pointed to the Lists web service located on my subsite, it was still returning the wrong list. I used the internal name for my list and now it works.
From the documentation on MSDN: It is recommended that you use the list GUID surrounded by curly braces (i.e., "{GUID}"), but you can also use the list display name.
Those curly braces seem to be missing in your call.
I found a partial answer to my problem. When I added the service reference to the subsite I am working on, for some reason app.config still contained a reference to the root Sharepoint site. Therefore the list I was looking for did not exist. Now I'm having another problem, though. I check the return value of the UpdateListItems() call, and I get the following error: "One or more field types are not installed properly. Go to the list settings page to delete these fields." I searched around and all of the problems that cause this error seem to involve having a field name with a space in it. Neither of my fields have spaces in them, though. Here is my updated code:
ListsService.Lists listService = new Risk_Form.ListsService.Lists();
listService.Credentials = System.Net.CredentialCache.DefaultCredentials;
XmlNode list = null;
list = listService.GetListAndView("Risks", "");
string listID = list.ChildNodes[0].Attributes["Name"].Value;
string viewID = list.ChildNodes[1].Attributes["Name"].Value;
string riskID = thisXDocument.DOM.selectSingleNode("//my:myFields/my:RiskID").text;
string headline = thisXDocument.DOM.selectSingleNode("//my:myFields/my:RiskHeadline").text;
XmlDocument doc = new XmlDocument();
XmlElement batch = doc.CreateElement("Batch");
batch.SetAttribute("OnError", "Continue");
batch.SetAttribute("ListVersion", "1");
batch.SetAttribute("ViewName", viewID);
batch.InnerXml =
"<Method ID='1' Cmd='New'>" +
"<Field Name='RiskID'>" + riskID + "</Field>" +
"<Field Name='Headline'>" + headline + "</Field>" +
"</Method>";
XmlNode ret = listService.UpdateListItems(listID, batch);
MessageBox.Show(ret.OuterXml);

How do you use the CopyIntoItems method of the SharePoint Copy web service?

I am attempting to load document files into a document library in SharePoint using the CopyIntoItems method of the SharePoint Copy web service.
The code below executes and returns 0 (success). Also, the CopyResult[] array returns 1 value with a "Success" result. However, I cannot find the document anywhere in the library.
I have two questions:
Can anyone see anything wrong with my code or suggest changes?
Can anyone suggest how I could debug this on the server side. I don't have a tremendous amount of experience with SharePoint. If I can track what is going on through logging or some other method on the server side it may help me figure out what is going on.
Code Sample:
string[] destinationUrls = { Uri.EscapeDataString("https://someaddress.com/Reports/Temp") };
SPCopyWebService.FieldInformation i1 = new SPCopyWebService.FieldInformation { DisplayName = "Name", InternalName = "Name", Type = SPListTransferSpike1.SPCopyWebService.FieldType.Text, Value = "Test1Name" };
SPCopyWebService.FieldInformation i2 = new SPCopyWebService.FieldInformation { DisplayName = "Title", InternalName = "Title", Type = SPListTransferSpike1.SPCopyWebService.FieldType.Text, Value = "Test1Title" };
SPCopyWebService.FieldInformation[] info = { i1, i2 };
SPCopyWebService.CopyResult[] result;
byte[] data = File.ReadAllBytes("C:\\SomePath\\Test1Data.txt");
uint ret = SPCopyNew.CopyIntoItems("", destinationUrls, info, data, out result);
Edit that got things working:
I got my code working by adding "http://null" to the SourceUrl field. Nat's answer below would probably work for that reason. Here is the line I changed to get it working.
// Change
uint ret = SPCopyNew.CopyIntoItems("http://null", destinationUrls, info, data, out result);
I think the issue may be in trying to set the "Name" property using the webservice. I have had some fail doing that.
Given the "Name" is the name of the document, you may have some success with
string targetDocName = "Test1Name.txt";
string destinationUrl = Uri.EscapeDataString("https://someaddress.com/Reports/Temp/" + targetDocName);
string[] destinationUrls = { destinationUrl };
SPCopyWebService.FieldInformation i1 = new SPCopyWebService.FieldInformation { DisplayName = "Title", InternalName = "Title", Type = SPListTransferSpike1.SPCopyWebService.FieldType.Text, Value = "Test1Title" };
SPCopyWebService.FieldInformation[] info = { i1};
SPCopyWebService.CopyResult[] result;
byte[] data = File.ReadAllBytes("C:\\SomePath\\Test1Data.txt");
uint ret = SPCopyNew.CopyIntoItems(destinationUrl, destinationUrls, info, data, out result);
Note: I have used the "target" as the "source" property. Don't quite know why, but it does the trick.
I didn't understand very well what you're tying to do, but if you're trying to upload a file from a local directory into a sharepoint library, i would suggest you create a webclient and use uploadata:
Example (VB.NET):
dim webclient as Webclient
webClient.UploadData("http://srvasddress/library/filenameexample.doc", "PUT", filebytes)
Then you just have to check in the file using the lists web service, something like:
listService.CheckInFile("http://srvasddress/library/filenameexample.doc", "description", "1")
Hope it was of some help.
EDIT: Don't forget to set credentials for the web client, etc.
EDIT 2: Update metada fields using this:
listService.UpdateListItems("Name of the Library, batchquery)
You can find info on building batch query's in here: link
The sourceurl is used in Sharepoint. It is a link back to the "Source Document." When in your document library, hover over the item, to the right appears a down pointing triangle. Clicking on it, brings up a menu. Click on the "View Properties" Option. On this page you will see the following "This item is a copy of http://null ( Go To Source Item | Unlink )"
Because we are using the Copy function Sharepoint is keeping track of the "Source item" as part of the Document Management feature.

Categories

Resources