Selenium: Find the base Url - c#

I'm using Selenium on different machines to automate testing of a MVC Web application.
My problem is that I can't get the base url for each machine.
I can get the current url using the following code:
IWebDriver driver = new FirefoxDriver();
string currentUrl = driver.Url;
But this doesn't help when I need to navigate to a different page.
Ideally I could just use the following to navigate to different pages:
driver.Navigate().GoToUrl(baseUrl+ "/Feedback");
driver.Navigate().GoToUrl(baseUrl+ "/Home");
A possible workaround I was using is:
string baseUrl = currentUrl.Remove(22); //remove everything from the current url but the base url
driver.Navigate().GoToUrl(baseUrl+ "/Feedback");
Is there a better way I could do this??

The best way around this would be to create a Uri instance of the URL.
This is because the Uri class in .NET already has code in place to do this exactly for you, so you should just use that. I'd go for something like (untested code):
string url = driver.Url; // get the current URL (full)
Uri currentUri = new Uri(url); // create a Uri instance of it
string baseUrl = currentUri.Authority; // just get the "base" bit of the URL
driver.Navigate().GoToUrl(baseUrl + "/Feedback");
Essentially, you are after the Authority property within the Uri class.
Note, there is a property that does a similar thing, called Host but this does not include port numbers, which your site does. It's something to bear in mind though.

Take the driver.Url, toss it into a new System.Uri, and use myUri.GetLeftPart(System.UriPartial.Authority).
If your base URL is http://localhost:12345/Login, this will return you http://localhost:12345.

Try this regular expression taken from this answer.
String baseUrl;
Pattern p = Pattern.compile("^(([a-zA-Z]+://)?[a-zA-Z0-9.-]+\\.[a-zA-Z]+(:\d+)?/");
Matcher m = p.matcher(str);
if (m.matches())
baseUrl = m.group(1);

Related

How to get current domain name in ASP.NET

I want to get the current domain name in asp.net c#.
I am using this code.
string DomainName = HttpContext.Current.Request.Url.Host;
My URL is localhost:5858but it's returning only localhost.
Now, I am using my project in localhost. I want to get localhost:5858.
For another example, when I am using this domain
www.somedomainname.com
I want to get somedomainname.com
Please give me an idea how to get the current domain name.
Try getting the “left part” of the url, like this:
string domainName = HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Authority);
This will give you either http://localhost:5858 or https://www.somedomainname.com whether you're on local or production. If you want to drop the www part, you should configure IIS to do so, but that's another topic.
Do note that the resulting URL will not have a trailing slash.
Using Request.Url.Host is appropriate - it's how you retrieve the value of the HTTP Host: header, which specifies which hostname (domain name) the UA (browser) wants, as the Resource-path part of the HTTP request does not include the hostname.
Note that localhost:5858 is not a domain name, it is an endpoint specifier, also known as an "authority", which includes the hostname and TCP port number. This is retrieved by accessing Request.Uri.Authority.
Furthermore, it is not valid to get somedomain.com from www.somedomain.com because a webserver could be configured to serve a different site for www.somedomain.com compared to somedomain.com, however if you are sure this is valid in your case then you'll need to manually parse the hostname, though using String.Split('.') works in a pinch.
Note that webserver (IIS) configuration is distinct from ASP.NET's configuration, and that ASP.NET is actually completely ignorant of the HTTP binding configuration of the websites and web-applications that it runs under. The fact that both IIS and ASP.NET share the same configuration files (web.config) is a red-herring.
Here is a screenshot of Request.RequestUri and all its properties for everyone's reference.
You can try the following code :
Request.Url.Host +
(Request.Url.IsDefaultPort ? "" : ":" + Request.Url.Port)
I use it like this in asp.net core 3.1
var url =Request.Scheme+"://"+ Request.Host.Value;
www.somedomain.com is the domain/host. The subdomain is an important part. www. is often used interchangeably with not having one, but that has to be set up as a rule (even if it's set by default) because they are not equivalent. Think of another subdomain, like mx.. That probably has a different target than www..
Given that, I'd advise not doing this sort of thing. That said, since you're asking I imagine you have a good reason.
Personally, I'd suggest special-casing www. for this.
string host = HttpContext.Current.Request.Url.GetComponents(UriComponents.HostAndPort, UriFormat.Unescaped);;
if (host.StartsWith("www."))
return host.Substring(4);
else
return host;
Otherwise, if you're really 100% sure that you want to chop off any subdomain, you'll need something a tad more complicated.
string host = ...;
int lastDot = host.LastIndexOf('.');
int secondToLastDot = host.Substring(0, lastDot).LastIndexOf('.');
if (secondToLastDot > -1)
return host.Substring(secondToLastDot + 1);
else
return host;
Getting the port is just like other people have said.
HttpContext.Current.Request.Url.Host is returning the correct values. If you run it on www.somedomainname.com it will give you www.somedomainname.com. If you want to get the 5858 as well you need to use
HttpContext.Current.Request.Url.Port
the Request.ServerVariables object works for me. I don't know of any reason not to use it.
ServerVariables["SERVER_NAME"] and ServerVariables["HTTP_URL"] should get what you're looking for
You can try the following code to get fully qualified domain name:
Request.Url.Scheme + System.Uri.SchemeDelimiter + Request.Url.Host
Here is a quick easy way to just get the name of the url.
var urlHost = HttpContext.Current.Request.Url.Host;
var xUrlHost = urlHost.Split('.');
foreach(var thing in xUrlHost)
{
if(thing != "www" && thing != "com")
{
urlHost = thing;
}
}
To get base URL in MVC even with subdomain www.somedomain.com/subdomain:
var url = $"{Request.Url.GetLeftPart(UriPartial.Authority)}{Url.Content("~/")}";
string domainName = HttpContext.Request.Host.Value;
this line should solve it
Try this:
#Request.Url.GetLeftPart(UriPartial.Authority)

How to get all urls from a webpage belonging to same Domain

Currently i am using this code to get the above :
Uri baseUri = new Uri(url);
Uri myUri = new Uri(baseUri, strRef);
domain = baseUri.Host;
Console.WriteLine(myUri.ToString());
strRef = myUri.ToString();
if (strRef.Contains(domain))
{
//THIS MEANS IT BELONGS TO SAME DOMAIN...
}
But using this code i am having some issue like suppose we have a main url = http://www.xxx.co.uk
Then the above code also treats a url like http://www.news.xxx.co.uk as external link ? Is this correct should it do that if not any one know a better solution for this?
I think you are in the correct path. But, to grab the latter mentioned URL (http://www.news.xxx.co.uk/) you could do a quick fix like this.
domain = baseUri.Host.Replace("www.", string.Empty);
Cheers!
vote if helpful.

Converting a web address to a valid href value

Firstly, this seems like something that should have been asked before, but I cannot find anything that answers my question.
A basic overview of my task is to render an anchor link on a web page which is based on a user defined web address. As the address is user defined this could be in any format, for example:
http://www.example.com
https://www.example.com
www.example.com
example.com
What I need to do with this value is to set it as the href property of an anchor tag. Now, the problem is that (in Chrome at least) only the first two examples will work due to the fact they are recognised as absolute URL paths. The last two examples will redirect to the same domain (i.e. treated as relative paths)
So the ultimate question is: What is the best way to format these values to ensure a consistent absolute path is used? I could check for http/https and add it if missing, but I was hoping there might be an out of the box .Net class that would be more reliable.
In addition, as this is a user defined value, it could be complete junk anyway so a function to validate the URL would be a nice bonus too.
We ran into this problem a few months back, and needed a consistent way of ensuring the URLs were absolute. We also wanted a way of removing http(s):// for displaying the URL on the web page.
I came up with this function:
public static string FormatUrl(string Url, bool IncludeHttp = null)
{
Url = Url.ToLower();
switch (IncludeHttp) {
case true:
if (!(Url.StartsWith("http://") || Url.StartsWith("https://")))
Url = "http://" + Url;
break;
case false:
if (Url.StartsWith("http://"))
Url = Url.Remove(0, "http://".Length);
if (Url.StartsWith("https://"))
Url = Url.Remove(0, "https://".Length);
break;
}
return Url;
}
I know you're after an "out of the box" library, but this may be of some help.
I think the problem with an "out of the box" solution would be that the function won't know whether the URL should be http:// or https://. With my function I've made an assumption that its going to be http://, but for some URLs you need https://. If Microsoft were to build something like this into the framework, it would be buggy from the start.
You can try using this overload of the Uri class:
Uri Constructor (String)
This constructor creates a Uri instance from a URI string. It parses the URI, puts it in canonical format, and makes any required escape encodings.
This constructor does not ensure that the Uri refers to an accessible resource.
This constructor assumes that the string parameter references an absolute URI and is equivalent to calling the Uri constructor with UriKind set to Absolute. If the string parameter passed to the constructor is a relative URI, this constructor will throw a UriFormatException.
This will try to construct a canonical Uri from the user input. And you have lots of properties to check and extract the URL parts that you need.

C# Screen Scraper - Handle long uri's

I'm building a html screen scraper, which parses urls, and then compare those with a set of other urls.
The comparison is done with Uri.AbsoluteUri or Uri.Host.
My problem is that when i'm creating a new Uri (new Uri(url)), an UriFormatException is thrown when the url is to long, or contains to many slashes.
Since my predefined set of urls contains several (to) long urls, I cannot just use substring to only fetch a part of the url.
What would be the best way to handle this?
Thanks
You can use Uri.TryCreate to check if the URI is valid before you new it.
You should not get an exception on a url this is so short. The folowing program runs well on VS2008:
static void Main(string[] args)
{
Uri uri = new Uri("http://stackoverflow.com/questions/1298985/c-screen-scraper-handle-long-uris/c-screen-scraper-handle-long-uris/c-screen-scraper-handle-long-uris/c-screen-scraper-handle-long-uris/c-screen-scraper-handle-long-uris/c-screen-scraper-handle-long-uris/c-screen-scraper-handle-long-uris/c-screen-scraper-handle-long-uris/");
Uri uri2 = new Uri("http://stackoverflow.com/questions/1298985/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/1/");
Console.ReadLine();
}

Truncating Query String & Returning Clean URL C# ASP.net

I would like to take the original URL, truncate the query string parameters, and return a cleaned up version of the URL. I would like it to occur across the whole application, so performing through the global.asax would be ideal. Also, I think a 301 redirect would be in order as well.
ie.
in: www.website.com/default.aspx?utm_source=twitter&utm_medium=social-media
out: www.website.com/default.aspx
What would be the best way to achieve this?
System.Uri is your friend here. This has many helpful utilities on it, but the one you want is GetLeftPart:
string url = "http://www.website.com/default.aspx?utm_source=twitter&utm_medium=social-media";
Uri uri = new Uri(url);
Console.WriteLine(uri.GetLeftPart(UriPartial.Path));
This gives the output: http://www.website.com/default.aspx
[The Uri class does require the protocol, http://, to be specified]
GetLeftPart basicallys says "get the left part of the uri up to and including the part I specify". This can be Scheme (just the http:// bit), Authority (the www.website.com part), Path (the /default.aspx) or Query (the querystring).
Assuming you are on an aspx web page, you can then use Response.Redirect(newUrl) to redirect the caller.
Here is a simple trick
Dim uri = New Uri(Request.Url.AbsoluteUri)
dim reqURL = uri.GetLeftPart(UriPartial.Path)
Here is a quick way of getting the root path sans the full path and query.
string path = Request.Url.AbsoluteUri.Replace(Request.Url.PathAndQuery,"");
This may look a little better.
string rawUrl = String.Concat(this.GetApplicationUrl(), Request.RawUrl);
if (rawUrl.Contains("/post/"))
{
bool hasQueryStrings = Request.QueryString.Keys.Count > 1;
if (hasQueryStrings)
{
Uri uri = new Uri(rawUrl);
rawUrl = uri.GetLeftPart(UriPartial.Path);
HtmlLink canonical = new HtmlLink();
canonical.Href = rawUrl;
canonical.Attributes["rel"] = "canonical";
Page.Header.Controls.Add(canonical);
}
}
Followed by a function to properly fetch the application URL.
Works perfectly.
I'm guessing that you want to do this because you want your users to see pretty looking URLs. The only way to get the client to "change" the URL in its address bar is to send it to a new location - i.e. you need to redirect them.
Are the query string parameters going to affect the output of your page? If so, you'll have to look at how to maintain state between requests (session variables, cookies, etc.) because your query string parameters will be lost as soon as you redirect to a page without them.
There are a few ways you can do this globally (in order of preference):
If you have direct control over your server environment then a configurable server module like ISAPI_ReWrite or IIS 7.0 URL Rewrite Module is a great approach.
A custom IHttpModule is a nice, reusable roll-your-own approach.
You can also do this in the global.asax as you suggest
You should only use the 301 response code if the resource has indeed moved permanently. Again, this depends on whether your application needs to use the query string parameters. If you use a permanent redirect a browser (that respects the 301 response code) will skip loading a URL like .../default.aspx?utm_source=twitter&utm_medium=social-media and load .../default.aspx - you'll never even know about the query string parameters.
Finally, you can use POST method requests. This gives you clean URLs and lets you pass parameters in, but will only work with <form> elements or requests you create using JavaScript.
Take a look at the UriBuilder class. You can create one with a url string, and the object will then parse this url and let you access just the elements you desire.
After completing whatever processing you need to do on the query string, just split the url on the question mark:
Dim _CleanUrl as String = Request.Url.AbsoluteUri.Split("?")(0)
Response.Redirect(_CleanUrl)
Granted, my solution is in VB.NET, but I'd imagine that it could be ported over pretty easily. And since we are only looking for the first element of the split, it even "fails" gracefully when there is no querystring.

Categories

Resources