Copy and paste the link from clipboard in selenium C# - c#

I'm having the following issue:
I'm saving the locators as
public static By CopyUrl = By.XPath("//a[#data-key='UrlLink']");
In the test, I cannot GetText(), or store the whole CopyUrl in a var, since it's void. Driver.Click(XPath.MainMenu.Tabs.CopyUrl);
How can I store the link which is saved in clipboard after I click on it, and paste it in a new tab.
I tried:
var elem =Driver.SwitchTo().NewWindow(WindowType.Tab).Navigate().GoToUrl("myCopiedUrl").ToString();
Driver.SwitchTo().NewWindow(WindowType.Tab).Navigate().GoToUrl(elem);

It is not working for you since both Click() and Navigate().GoToUrl() methods are returning void.
In order to get the current URL you should use this method:
String currentURL = driver.Url;
or
String currentURL = driver.getCurrentUrl();
or
String currentURL = driver.getLocation();

[Test, Order(01234)]
public void t_Document_CopyUrl_Downloaded()
{
NavigateToYourPage();
UploadNewDocument();
NavigateToTheSpecificTab();
//Click on "Copy URL"
string fileName = Driver.FindElement(XPath.Input).GetValue();
IWebElement copyUrl = Driver.FindElement(XPath.CopyUrl);
string currentUrl = copyUrl.GetAttribute("textContent");
Driver.Click(XPath.CopyUrl);
Driver.WaitForNoSpinner();
// Opens a new tab and switches to new tab
Driver.SwitchTo().NewWindow(WindowType.Tab);
Driver.Navigate().GoToUrl(currentUrl);
Driver.Navigate().GoToUrl("chrome://downloads/");
string downloadedFileName = Driver.ExecuteJavaScript<string>("return document.querySelector('downloads-manager').shadowRoot.querySelector('downloads-item').shadowRoot.querySelector('#name').textContent;");
Driver.SwitchTo().Window(Driver.WindowHandles[0]);
Assert.IsTrue(downloadedFileName.StartsWith(fileName));
}

Related

C# console application code doesn't execute after await

I'm trying to make a webscraper where I get all the download links for the css/js/images from a html file.
Problem
The first breakpoint does hit, but the second one not after hitting "Continue".
Picture in Visual Studio
Code I'm talking about:
private static async void GetHtml(string url, string downloadDir)
{
//Get html data, create and load htmldocument
HttpClient httpClient = new HttpClient();
//This code gets executed
var html = await httpClient.GetStringAsync(url);
//This code not
Console.ReadLine();
var htmlDocument = new HtmlDocument();
htmlDocument.LoadHtml(html);
//Get all css download urls
var linkUrl = htmlDocument.DocumentNode.Descendants("link")
.Where(node => node.GetAttributeValue("type", "")
.Equals("text/css"))
.Select(node=>node.GetAttributeValue("href",""))
.ToList();
//Downloading css, js, images and source code
using (var client = new WebClient())
{
for (var i = 0; i <scriptUrl.Count; i++)
{
Uri uri = new Uri(scriptUrl[i]);
client.DownloadFile(uri,
downloadDir + #"\js\" + uri.Segments.Last());
}
}
Edit
Im calling the getHtml method from here:
private static void Start()
{
//Create a list that will hold the names of all the subpages
List<string> subpagesList = new List<string>();
//Ask user for url and asign that to var url, also add the url to the url list
Console.WriteLine("Geef url van de website:");
string url = "https://www.hethwc.nl";
//Ask user for download directory and assign that to var downloadDir
Console.WriteLine("Geef locatie voor download:");
var downloadDir = #"C:\Users\Daniel\Google Drive\Almere\C# II\Download tests\hethwc\";
//Download and save the index file
var htmlSource = new System.Net.WebClient().DownloadString(url);
System.IO.File.WriteAllText(#"C:\Users\Daniel\Google Drive\Almere\C# II\Download tests\hethwc\index.html", htmlSource);
// Creating directories
string jsDirectory = System.IO.Path.Combine(downloadDir, "js");
string cssDirectory = System.IO.Path.Combine(downloadDir, "css");
string imagesDirectory = System.IO.Path.Combine(downloadDir, "images");
System.IO.Directory.CreateDirectory(jsDirectory);
System.IO.Directory.CreateDirectory(cssDirectory);
System.IO.Directory.CreateDirectory(imagesDirectory);
GetHtml("https://www.hethwc.nu", downloadDir);
}
How are you calling GetHtml? Presumably that is from a sync Main method, and you don't have any other non-worker thread in play (because your main thread exited): the process will terminate. Something like:
static void Main() {
GetHtml();
}
The above will terminate the process immediately after GetHtml returns and the Main method ends, which will be at the first incomplete await point.
In current C# versions (C# 7.1 onwards) you can create an async Task Main() method, which will allow you to await your GetHtml method properly, as long as you change GetHtml to return Task:
async static Task Main() {
await GetHtml();
}

Get Path of the document from IWpfTextView for non cs files

I want to add some buttons to the text editor in VS. In the ViewPortTextViewCreationListener when ViewPort manager is created I would like to know the path of the document or it
public void TextViewCreated(IWpfTextView textView) {
var result = _textDocumentFactoryService.TryGetTextDocument(TextView.TextBuffer, out ITextDocument textDocument);
new ViewPortSwitcher(textView);
}
I've tried to use ITextDocumentFactoryService to get ITextDocument from TextBuffer (see answer here). If I open cs file it works properly. But if I open cshtml file TryGetTextDocument returns false.
Finally, I've found the solution see MSDN forum:
public static string GetPath(this IWpfTextView textView) {
textView.TextBuffer.Properties.TryGetProperty(typeof(IVsTextBuffer), out IVsTextBuffer bufferAdapter);
var persistFileFormat = bufferAdapter as IPersistFileFormat;
if (persistFileFormat == null) {
return null;
}
persistFileFormat.GetCurFile(out string filePath, out _);
return filePath;
}

String Replace issues

I'm trying to replace all instances of a variable in text file using this function
public static string GetTextContent(string location, string callbackfromasync)
{
var markup = HttpContext.Current.Server.MapPath(location);
var correctString = markup.Replace("callbackUrl", callbackfromasync);
return File.ReadAllText(correctString);
}
I am calling the method like this:
await UserManager.SendEmailAsync(user.Id, "Confirm your account", GetTextContent(GetRegistrationEmailMarkUp, callbackUrl));
GetRegistrationEmailMarkUp should return a string of HTML.
The markup I'm working with looks like this.
Why is the string not being replaced?
You've got the operations mixed up. You need to get the data from the file to modify it, not modify the path of the file:
string markupFile = HttpContext.Current.Server.MapPath(location);
string markupTemplate = File.ReadAllText(markupFile);
string modifiedHtml = markupTemplate.Replace("callbackUrl", callbackfromasync);
return modifiedHtml;

Get Last two folder's name from URL using C#

I have a URL and from which i need to get names after "bussiness" and Before the Page Name i.e. "paradise-villas-little.aspx" from below URL.
http://test.com/anc/bussiness/accommo/resort/paradise-villas-little.aspx
I am not getting how can i get this. i have tried the RawUrl, but it fetched the full. Please help me how can i do this.
UPDATE: This is a type of URL, i need to check it for dynamically.
You can create a little helper, and parse the URL from it's Uri Segments :
public static class Helper
{
public static IEnumerable<String> ExtractSegments(this Uri uri, String exclusiveStart)
{
bool startFound = false;
foreach (var seg in uri.Segments.Select(i => i.Replace(#"/","")))
{
if (startFound == false)
{
if (seg == exclusiveStart)
startFound = true;
}
else
{
if (!seg.Contains("."))
yield return seg;
}
}
}
}
And call it like this :
Uri uri = new Uri(#"http://test.com/anc/bussiness/accommo/resort/paradise-villas-little.aspx");
var found = uri.ExtractSegments("bussiness").ToList();
Then found contains "accommo" and "resort", and this method is extensible to any URL length, with or without file name at the end.
Nothing sophisticated in this implementation, just regular string operations:
string url = "http://test.com/anc/bussiness/accommo/resort/paradise-villas-little.aspx";
string startAfter = "business";
string pageName = "paradise-villas-little.aspx";
char delimiter = '/'; //not platform specific
var from = url.IndexOf(startAfter) + startAfter.Length + 1;
var to = url.Length - from - pageName.Length - 1;
var strings = url.Substring(from, to).Split(delimiter);
You may want to add validations though.
You have to use built-in string methods. The best is to use String Split.
String url = "http://test.com/anc/bussiness/accommo/resort/paradise-villas-little.aspx";
String[] url_parts = url.Split('/'); //Now you have all the parts of the URL all folders and page. Access the folder names from string array.
Hope this helps

Opening a hyperlink generated dynamically with a string command

Backstory,
So I am working on a personal assistant program and all my voice commands are translated into strings for parsing.
I have set up the ability to search Google and display the results in a text block as hyperlinks.
Now I want to be able to set up the ability to open these links with speech(string commands). So far I have the following.
This bit allows me to search using the Google Custom Search API with a custom "GoogleSearch" class.
public void search_google(string query) //Google Searching
{
#region link strings
string result_1 = "";
string result_2 = "";
string result_3 = "";
string result_4 = "";
string result_5 = "";
string result_6 = "";
string result_7 = "";
string result_8 = "";
string result_9 = "";
string result_10 = "";
#endregion
GoogleSearch search = new GoogleSearch()
{
Key = "{apikey}",
CX = "{cxkey}"
};
search.SearchCompleted += (a, b) =>
{
tab_control.SelectedIndex = 2;
int p = 1;
search_results.Text = String.Empty;
foreach (Item i in b.Response.Items)
{
Hyperlink hyperLink = new Hyperlink()
{
NavigateUri = new Uri(i.Link)
};
hyperLink.Inlines.Add(i.Title);
hyperLink.RequestNavigate += Hyperlink_RequestNavigate;
hyperLink.Name = "result_" + p;
//search_results.Inlines.Add(hyperLink.Name);
search_results.Inlines.Add(Environment.NewLine);
search_results.Inlines.Add(hyperLink);
search_results.Inlines.Add(Environment.NewLine);
search_results.Inlines.Add(i.Snippet);
search_results.Inlines.Add(Environment.NewLine);
search_results.Inlines.Add(Environment.NewLine);
p++;
};
};
search.Search(query);
}
It outputs my results in a series of hyperlinks and text snippets into a text block that I set up on the main window. The search process is triggered by my input parser which looks for the keywords "search" or "Google".
The next step would be the input parser checking for keyword "result" to look for the hyperlink to open. Here is the unfinished code for that.
if ((Input.Contains("result") || Input.Contains("Result")) && tab_control.TabIndex == 2)
{
int result_number = 0;
switch(result_number)
{
case 1:
if (Input.Contains("first") || Input.Contains("1st"))
{
// open hyperlink with name property result_1
}
break;
case 2:
// additional cases added up to 10 with similar syntax for parsing.
}
}
You can open a hyperlink in the default browser using:
Process.Start(myHyperlink);
EDIT
Based on your comments, it seems you are having trouble accessing result_1 (etc.).
You define result_1 as a variable local to the method search_google()
public void search_google(string query) //Google Searching
{
#region link strings
string result_1 = "";
That means result_1 is only visible within that method.
Your if and switch statements do not appear to be part of search_google(), so they can never see result_1. If those statements are in a different method, you can work around that issue by moving result_1 to the class level (outside of search_google()).
ON a site note, rather than defining ten individual result strings, you probably want to use an array of strings or a list of strings.

Categories

Resources