blob: edec97e6200ea8971da7ba7a12f6cb72c383df0a [file] [log] [blame] [edit]
// <copyright file="CookieImplementationTest.cs" company="Selenium Committers">
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
// </copyright>
using NUnit.Framework;
using OpenQA.Selenium.Environment;
using OpenQA.Selenium.Internal;
using System;
using System.Collections.ObjectModel;
using System.Text;
using System.Text.RegularExpressions;
namespace OpenQA.Selenium;
[TestFixture]
public class CookieImplementationTest : DriverTestFixture
{
private Random random = new Random();
private bool isOnAlternativeHostName;
private string hostname;
[SetUp]
public void GoToSimplePageAndDeleteCookies()
{
GotoValidDomainAndClearCookies("animals");
AssertNoCookiesArePresent();
}
[Test]
public void ShouldGetCookieByName()
{
if (!CheckIsOnValidHostNameForCookieTests())
{
return;
}
string key = string.Format("key_{0}", new Random().Next());
((IJavaScriptExecutor)driver).ExecuteScript("document.cookie = arguments[0] + '=set';", key);
Cookie cookie = driver.Manage().Cookies.GetCookieNamed(key);
Assert.That(cookie.Value, Is.EqualTo("set"));
}
[Test]
public void ShouldBeAbleToAddCookie()
{
if (!CheckIsOnValidHostNameForCookieTests())
{
return;
}
string key = GenerateUniqueKey();
string value = "foo";
Cookie cookie = new Cookie(key, value);
AssertCookieIsNotPresentWithName(key);
driver.Manage().Cookies.AddCookie(cookie);
AssertCookieHasValue(key, value);
Assert.That(driver.Manage().Cookies.AllCookies, Does.Contain(cookie), "Cookie was not added successfully");
}
[Test]
public void GetAllCookies()
{
if (!CheckIsOnValidHostNameForCookieTests())
{
return;
}
string key1 = GenerateUniqueKey();
string key2 = GenerateUniqueKey();
AssertCookieIsNotPresentWithName(key1);
AssertCookieIsNotPresentWithName(key2);
ReadOnlyCollection<Cookie> cookies = driver.Manage().Cookies.AllCookies;
int count = cookies.Count;
Cookie one = new Cookie(key1, "value");
Cookie two = new Cookie(key2, "value");
driver.Manage().Cookies.AddCookie(one);
driver.Manage().Cookies.AddCookie(two);
driver.Url = simpleTestPage;
cookies = driver.Manage().Cookies.AllCookies;
Assert.That(cookies, Has.Count.EqualTo(count + 2));
Assert.That(cookies, Does.Contain(one));
Assert.That(cookies, Does.Contain(two));
}
[Test]
public void DeleteAllCookies()
{
if (!CheckIsOnValidHostNameForCookieTests())
{
return;
}
((IJavaScriptExecutor)driver).ExecuteScript("document.cookie = 'foo=set';");
AssertSomeCookiesArePresent();
driver.Manage().Cookies.DeleteAllCookies();
AssertNoCookiesArePresent();
}
[Test]
public void DeleteCookieWithName()
{
if (!CheckIsOnValidHostNameForCookieTests())
{
return;
}
string key1 = GenerateUniqueKey();
string key2 = GenerateUniqueKey();
((IJavaScriptExecutor)driver).ExecuteScript("document.cookie = arguments[0] + '=set';", key1);
((IJavaScriptExecutor)driver).ExecuteScript("document.cookie = arguments[0] + '=set';", key2);
AssertCookieIsPresentWithName(key1);
AssertCookieIsPresentWithName(key2);
driver.Manage().Cookies.DeleteCookieNamed(key1);
AssertCookieIsNotPresentWithName(key1);
AssertCookieIsPresentWithName(key2);
}
[Test]
public void ShouldNotDeleteCookiesWithASimilarName()
{
if (!CheckIsOnValidHostNameForCookieTests())
{
return;
}
string cookieOneName = "fish";
Cookie cookie1 = new Cookie(cookieOneName, "cod");
Cookie cookie2 = new Cookie(cookieOneName + "x", "earth");
IOptions options = driver.Manage();
AssertCookieIsNotPresentWithName(cookie1.Name);
options.Cookies.AddCookie(cookie1);
options.Cookies.AddCookie(cookie2);
AssertCookieIsPresentWithName(cookie1.Name);
options.Cookies.DeleteCookieNamed(cookieOneName);
Assert.That(driver.Manage().Cookies.AllCookies, Does.Not.Contain(cookie1));
Assert.That(driver.Manage().Cookies.AllCookies, Does.Contain(cookie2));
}
[Test]
public void AddCookiesWithDifferentPathsThatAreRelatedToOurs()
{
if (!CheckIsOnValidHostNameForCookieTests())
{
return;
}
string basePath = EnvironmentManager.Instance.UrlBuilder.Path;
Cookie cookie1 = new Cookie("fish", "cod", "/" + basePath + "/animals");
Cookie cookie2 = new Cookie("planet", "earth", "/" + basePath + "/");
IOptions options = driver.Manage();
options.Cookies.AddCookie(cookie1);
options.Cookies.AddCookie(cookie2);
UrlBuilder builder = EnvironmentManager.Instance.UrlBuilder;
driver.Url = builder.WhereIs("animals");
ReadOnlyCollection<Cookie> cookies = options.Cookies.AllCookies;
AssertCookieIsPresentWithName(cookie1.Name);
AssertCookieIsPresentWithName(cookie2.Name);
driver.Url = builder.WhereIs("simpleTest.html");
AssertCookieIsNotPresentWithName(cookie1.Name);
}
[Test]
[IgnoreBrowser(Browser.Firefox, "https://github.com/mozilla/geckodriver/issues/1104")]
public void GetCookiesInAFrame()
{
driver.Url = EnvironmentManager.Instance.UrlBuilder.WhereIs("animals");
Cookie cookie1 = new Cookie("fish", "cod", "/common/animals");
driver.Manage().Cookies.AddCookie(cookie1);
driver.Url = EnvironmentManager.Instance.UrlBuilder.WhereIs("frameWithAnimals.html");
AssertCookieIsNotPresentWithName(cookie1.Name);
driver.SwitchTo().Frame("iframe1");
AssertCookieIsPresentWithName(cookie1.Name);
}
[Test]
public void CannotGetCookiesWithPathDifferingOnlyInCase()
{
if (!CheckIsOnValidHostNameForCookieTests())
{
return;
}
string cookieName = "fish";
driver.Manage().Cookies.AddCookie(new Cookie(cookieName, "cod", "/Common/animals"));
driver.Url = EnvironmentManager.Instance.UrlBuilder.WhereIs("animals");
Assert.That(driver.Manage().Cookies.GetCookieNamed(cookieName), Is.Null);
}
[Test]
public void ShouldNotGetCookieOnDifferentDomain()
{
if (!CheckIsOnValidHostNameForCookieTests())
{
return;
}
string cookieName = "fish";
driver.Manage().Cookies.AddCookie(new Cookie(cookieName, "cod"));
AssertCookieIsPresentWithName(cookieName);
driver.Url = EnvironmentManager.Instance.UrlBuilder.WhereElseIs("simpleTest.html");
AssertCookieIsNotPresentWithName(cookieName);
}
[Test]
public void ShouldBeAbleToAddToADomainWhichIsRelatedToTheCurrentDomain()
{
if (!CheckIsOnValidHostNameForCookieTests())
{
return;
}
// Cookies cannot be set on domain names with less than 2 dots, so
// localhost is out. If we are in that boat, bail the test.
string hostName = EnvironmentManager.Instance.UrlBuilder.HostName;
string[] hostNameParts = hostName.Split(new char[] { '.' });
if (hostNameParts.Length < 3)
{
Assert.Ignore("Skipping test: Cookies can only be set on fully-qualified domain names.");
}
AssertCookieIsNotPresentWithName("name");
Regex replaceRegex = new Regex(".*?\\.");
string shorter = replaceRegex.Replace(this.hostname, ".", 1);
Cookie cookie = new Cookie("name", "value", shorter, "/", GetTimeInTheFuture());
driver.Manage().Cookies.AddCookie(cookie);
AssertCookieIsPresentWithName("name");
}
[Test]
[IgnoreBrowser(Browser.IE, "IE does not want to set cookie")]
public void ShouldNotGetCookiesRelatedToCurrentDomainWithoutLeadingPeriod()
{
if (!CheckIsOnValidHostNameForCookieTests())
{
return;
}
string cookieName = "name";
AssertCookieIsNotPresentWithName(cookieName);
Regex replaceRegex = new Regex(".*?\\.");
string subdomain = replaceRegex.Replace(this.hostname, "subdomain.", 1);
Cookie cookie = new Cookie(cookieName, "value", subdomain, "/", GetTimeInTheFuture());
string originalUrl = driver.Url;
string subdomainUrl = originalUrl.Replace(this.hostname, subdomain);
driver.Url = subdomainUrl;
driver.Manage().Cookies.AddCookie(cookie);
driver.Url = originalUrl;
AssertCookieIsNotPresentWithName(cookieName);
}
[Test]
public void ShouldBeAbleToIncludeLeadingPeriodInDomainName()
{
if (!CheckIsOnValidHostNameForCookieTests())
{
return;
}
// Cookies cannot be set on domain names with less than 2 dots, so
// localhost is out. If we are in that boat, bail the test.
string hostName = EnvironmentManager.Instance.UrlBuilder.HostName;
string[] hostNameParts = hostName.Split(new char[] { '.' });
if (hostNameParts.Length < 3)
{
Assert.Ignore("Skipping test: Cookies can only be set on fully-qualified domain names.");
}
AssertCookieIsNotPresentWithName("name");
// Replace the first part of the name with a period
Regex replaceRegex = new Regex(".*?\\.");
string shorter = replaceRegex.Replace(this.hostname, ".", 1);
Cookie cookie = new Cookie("name", "value", shorter, "/", DateTime.Now.AddSeconds(100000));
driver.Manage().Cookies.AddCookie(cookie);
AssertCookieIsPresentWithName("name");
}
[Test]
public void ShouldBeAbleToSetDomainToTheCurrentDomain()
{
if (!CheckIsOnValidHostNameForCookieTests())
{
return;
}
// Cookies cannot be set on domain names with less than 2 dots, so
// localhost is out. If we are in that boat, bail the test.
string hostName = EnvironmentManager.Instance.UrlBuilder.HostName;
string[] hostNameParts = hostName.Split(new char[] { '.' });
if (hostNameParts.Length < 3)
{
Assert.Ignore("Skipping test: Cookies can only be set on fully-qualified domain names.");
}
Uri url = new Uri(driver.Url);
String host = url.Host + ":" + url.Port.ToString();
Cookie cookie1 = new Cookie("fish", "cod", host, "/", null);
IOptions options = driver.Manage();
options.Cookies.AddCookie(cookie1);
driver.Url = javascriptPage;
ReadOnlyCollection<Cookie> cookies = options.Cookies.AllCookies;
Assert.That(cookies, Does.Contain(cookie1));
}
[Test]
public void ShouldWalkThePathToDeleteACookie()
{
if (!CheckIsOnValidHostNameForCookieTests())
{
return;
}
string basePath = EnvironmentManager.Instance.UrlBuilder.Path;
Cookie cookie1 = new Cookie("fish", "cod");
driver.Manage().Cookies.AddCookie(cookie1);
int count = driver.Manage().Cookies.AllCookies.Count;
driver.Url = childPage;
Cookie cookie2 = new Cookie("rodent", "hamster", "/" + basePath + "/child");
driver.Manage().Cookies.AddCookie(cookie2);
count = driver.Manage().Cookies.AllCookies.Count;
driver.Url = grandchildPage;
Cookie cookie3 = new Cookie("dog", "dalmatian", "/" + basePath + "/child/grandchild/");
driver.Manage().Cookies.AddCookie(cookie3);
count = driver.Manage().Cookies.AllCookies.Count;
driver.Url = (EnvironmentManager.Instance.UrlBuilder.WhereIs("child/grandchild"));
driver.Manage().Cookies.DeleteCookieNamed("rodent");
count = driver.Manage().Cookies.AllCookies.Count;
Assert.That(driver.Manage().Cookies.GetCookieNamed("rodent"), Is.Null);
ReadOnlyCollection<Cookie> cookies = driver.Manage().Cookies.AllCookies;
Assert.That(cookies, Has.Exactly(2).Items);
Assert.That(cookies, Does.Contain(cookie1));
Assert.That(cookies, Does.Contain(cookie3));
driver.Manage().Cookies.DeleteAllCookies();
driver.Url = grandchildPage;
AssertNoCookiesArePresent();
}
[Test]
public void ShouldIgnoreThePortNumberOfTheHostWhenSettingTheCookie()
{
if (!CheckIsOnValidHostNameForCookieTests())
{
return;
}
// Cookies cannot be set on domain names with less than 2 dots, so
// localhost is out. If we are in that boat, bail the test.
string hostName = EnvironmentManager.Instance.UrlBuilder.HostName;
string[] hostNameParts = hostName.Split(new char[] { '.' });
if (hostNameParts.Length < 3)
{
Assert.Ignore("Skipping test: Cookies can only be set on fully-qualified domain names.");
}
Uri uri = new Uri(driver.Url);
string host = string.Format("{0}:{1}", uri.Host, uri.Port);
string cookieName = "name";
AssertCookieIsNotPresentWithName(cookieName);
Cookie cookie = new Cookie(cookieName, "value", host, "/", null);
driver.Manage().Cookies.AddCookie(cookie);
AssertCookieIsPresentWithName(cookieName);
}
[Test]
public void CookieEqualityAfterSetAndGet()
{
if (!CheckIsOnValidHostNameForCookieTests())
{
return;
}
DateTime time = DateTime.Now.AddDays(1);
Cookie cookie1 = new Cookie("fish", "cod", null, "/common/animals", time);
IOptions options = driver.Manage();
options.Cookies.AddCookie(cookie1);
ReadOnlyCollection<Cookie> cookies = options.Cookies.AllCookies;
Cookie retrievedCookie = null;
foreach (Cookie tempCookie in cookies)
{
if (cookie1.Equals(tempCookie))
{
retrievedCookie = tempCookie;
break;
}
}
Assert.That(retrievedCookie, Is.Not.Null);
//Cookie.equals only compares name, domain and path
Assert.That(retrievedCookie, Is.EqualTo(cookie1));
}
[Test]
public void ShouldRetainCookieExpiry()
{
if (!CheckIsOnValidHostNameForCookieTests())
{
return;
}
// DateTime.Now contains milliseconds; the returned cookie expire date
// will not. So we need to truncate the milliseconds.
DateTime current = DateTime.Now;
DateTime expireDate = new DateTime(current.Year, current.Month, current.Day, current.Hour, current.Minute, current.Second, DateTimeKind.Local).AddDays(1);
Cookie addCookie = new Cookie("fish", "cod", "/common/animals", expireDate);
IOptions options = driver.Manage();
options.Cookies.AddCookie(addCookie);
Cookie retrieved = options.Cookies.GetCookieNamed("fish");
Assert.That(retrieved, Is.Not.Null);
Assert.That(retrieved.Expiry, Is.EqualTo(addCookie.Expiry), "Cookies are not equal");
}
[Test]
[Ignore("Unable to open secure url")]
[IgnoreBrowser(Browser.IE, "Browser does not handle untrusted SSL certificates.")]
public void CanHandleSecureCookie()
{
driver.Url = EnvironmentManager.Instance.UrlBuilder.WhereIsSecure("animals");
Cookie addedCookie = new ReturnedCookie("fish", "cod", null, "/common/animals", null, true, false, null);
driver.Manage().Cookies.AddCookie(addedCookie);
driver.Navigate().Refresh();
Cookie retrieved = driver.Manage().Cookies.GetCookieNamed("fish");
Assert.That(retrieved, Is.Not.Null);
}
[Test]
[Ignore("Unable to open secure url")]
[IgnoreBrowser(Browser.IE, "Browser does not handle untrusted SSL certificates.")]
public void ShouldRetainCookieSecure()
{
driver.Url = EnvironmentManager.Instance.UrlBuilder.WhereIsSecure("animals");
ReturnedCookie addedCookie = new ReturnedCookie("fish", "cod", string.Empty, "/common/animals", null, true, false, null);
driver.Manage().Cookies.AddCookie(addedCookie);
driver.Navigate().Refresh();
Cookie retrieved = driver.Manage().Cookies.GetCookieNamed("fish");
Assert.That(retrieved, Is.Not.Null);
Assert.That(retrieved.Secure, "Secure attribute not set to true");
}
[Test]
public void CanHandleHttpOnlyCookie()
{
StringBuilder url = new StringBuilder(EnvironmentManager.Instance.UrlBuilder.WhereIs("cookie"));
url.Append("?action=add");
url.Append("&name=").Append("fish");
url.Append("&value=").Append("cod");
url.Append("&path=").Append("/common/animals");
url.Append("&httpOnly=").Append("true");
driver.Url = url.ToString();
driver.Url = EnvironmentManager.Instance.UrlBuilder.WhereIs("animals");
Cookie retrieved = driver.Manage().Cookies.GetCookieNamed("fish");
Assert.That(retrieved, Is.Not.Null);
}
[Test]
public void ShouldRetainHttpOnlyFlag()
{
StringBuilder url = new StringBuilder(EnvironmentManager.Instance.UrlBuilder.WhereElseIs("cookie"));
url.Append("?action=add");
url.Append("&name=").Append("fish");
url.Append("&value=").Append("cod");
url.Append("&path=").Append("/common/animals");
url.Append("&httpOnly=").Append("true");
driver.Url = url.ToString();
driver.Url = EnvironmentManager.Instance.UrlBuilder.WhereElseIs("animals");
Cookie retrieved = driver.Manage().Cookies.GetCookieNamed("fish");
Assert.That(retrieved, Is.Not.Null);
Assert.That(retrieved.IsHttpOnly, "HttpOnly attribute not set to true");
}
[Test]
public void SettingACookieThatExpiredInThePast()
{
DateTime expires = DateTime.Now.AddSeconds(-1000);
Cookie cookie = new Cookie("expired", "yes", "/common/animals", expires);
IOptions options = driver.Manage();
options.Cookies.AddCookie(cookie);
cookie = options.Cookies.GetCookieNamed("expired");
Assert.That(cookie, Is.Null, "Cookie expired before it was set, so nothing should be returned: " + cookie);
}
[Test]
public void CanSetCookieWithoutOptionalFieldsSet()
{
if (!CheckIsOnValidHostNameForCookieTests())
{
return;
}
string key = GenerateUniqueKey();
string value = "foo";
Cookie cookie = new Cookie(key, value);
AssertCookieIsNotPresentWithName(key);
driver.Manage().Cookies.AddCookie(cookie);
AssertCookieHasValue(key, value);
}
[Test]
public void DeleteNotExistedCookie()
{
String key = GenerateUniqueKey();
AssertCookieIsNotPresentWithName(key);
driver.Manage().Cookies.DeleteCookieNamed(key);
}
[Test]
[IgnoreBrowser(Browser.IE, "IE does not want to set cookie")]
public void DeleteAllCookiesDifferentUrls()
{
if (!CheckIsOnValidHostNameForCookieTests())
{
return;
}
Cookie cookie1 = new Cookie("fish1", "cod", EnvironmentManager.Instance.UrlBuilder.HostName, null, null);
Cookie cookie2 = new Cookie("fish2", "tune", EnvironmentManager.Instance.UrlBuilder.AlternateHostName, null, null);
string url1 = EnvironmentManager.Instance.UrlBuilder.WhereIs("");
string url2 = EnvironmentManager.Instance.UrlBuilder.WhereElseIs("");
IOptions options = driver.Manage();
options.Cookies.AddCookie(cookie1);
AssertCookieIsPresentWithName(cookie1.Name);
driver.Url = url2;
options.Cookies.AddCookie(cookie2);
AssertCookieIsNotPresentWithName(cookie1.Name);
AssertCookieIsPresentWithName(cookie2.Name);
driver.Url = url1;
AssertCookieIsPresentWithName(cookie1.Name);
AssertCookieIsNotPresentWithName(cookie2.Name);
options.Cookies.DeleteAllCookies();
AssertCookieIsNotPresentWithName(cookie1.Name);
driver.Url = url2;
AssertCookieIsPresentWithName(cookie2.Name);
}
[Test]
[TestCase(null)]
[TestCase("")]
[TestCase(" ")]
public void ShouldThrowWhenGetInvalidCookieByName(string cookieName)
{
var getCookieAction = () => driver.Manage().Cookies.GetCookieNamed(cookieName);
Assert.That(getCookieAction, Throws.ArgumentException);
}
[Test]
[TestCase(null)]
[TestCase("")]
[TestCase(" ")]
public void ShouldThrowWhenDeleteInvalidCookieByName(string cookieName)
{
var deleteCookieAction = () => driver.Manage().Cookies.DeleteCookieNamed(cookieName);
Assert.That(deleteCookieAction, Throws.ArgumentException);
}
//------------------------------------------------------------------
// Tests below here are not included in the Java test suite
//------------------------------------------------------------------
[Test]
public void CanSetCookiesOnADifferentPathOfTheSameHost()
{
if (!CheckIsOnValidHostNameForCookieTests())
{
return;
}
string basePath = EnvironmentManager.Instance.UrlBuilder.Path;
Cookie cookie1 = new Cookie("fish", "cod", "/" + basePath + "/animals");
Cookie cookie2 = new Cookie("planet", "earth", "/" + basePath + "/galaxy");
IOptions options = driver.Manage();
ReadOnlyCollection<Cookie> count = options.Cookies.AllCookies;
options.Cookies.AddCookie(cookie1);
options.Cookies.AddCookie(cookie2);
string url = EnvironmentManager.Instance.UrlBuilder.WhereIs("animals");
driver.Url = url;
ReadOnlyCollection<Cookie> cookies = options.Cookies.AllCookies;
Assert.That(cookies, Does.Contain(cookie1));
Assert.That(cookies, Does.Not.Contain(cookie2));
driver.Url = EnvironmentManager.Instance.UrlBuilder.WhereIs("galaxy");
cookies = options.Cookies.AllCookies;
Assert.That(cookies, Does.Not.Contain(cookie1));
Assert.That(cookies, Does.Contain(cookie2));
}
[Test]
public void ShouldNotBeAbleToSetDomainToSomethingThatIsUnrelatedToTheCurrentDomain()
{
if (!CheckIsOnValidHostNameForCookieTests())
{
return;
}
Cookie cookie1 = new Cookie("fish", "cod");
IOptions options = driver.Manage();
options.Cookies.AddCookie(cookie1);
string url = EnvironmentManager.Instance.UrlBuilder.WhereElseIs("simpleTest.html");
driver.Url = url;
Assert.That(options.Cookies.GetCookieNamed("fish"), Is.Null);
}
[Test]
public void GetCookieDoesNotRetrieveBeyondCurrentDomain()
{
if (!CheckIsOnValidHostNameForCookieTests())
{
return;
}
Cookie cookie1 = new Cookie("fish", "cod");
IOptions options = driver.Manage();
options.Cookies.AddCookie(cookie1);
String url = EnvironmentManager.Instance.UrlBuilder.WhereElseIs("");
driver.Url = url;
ReadOnlyCollection<Cookie> cookies = options.Cookies.AllCookies;
Assert.That(cookies, Does.Not.Contain(cookie1));
}
[Test]
public void ShouldAddCookieToCurrentDomainAndPath()
{
if (!CheckIsOnValidHostNameForCookieTests())
{
return;
}
// Cookies cannot be set on domain names with less than 2 dots, so
// localhost is out. If we are in that boat, bail the test.
string hostName = EnvironmentManager.Instance.UrlBuilder.HostName;
string[] hostNameParts = hostName.Split(new char[] { '.' });
if (hostNameParts.Length < 3)
{
Assert.Ignore("Skipping test: Cookies can only be set on fully-qualified domain names.");
}
driver.Url = macbethPage;
IOptions options = driver.Manage();
Cookie cookie = new Cookie("Homer", "Simpson", this.hostname, "/" + EnvironmentManager.Instance.UrlBuilder.Path, null);
options.Cookies.AddCookie(cookie);
ReadOnlyCollection<Cookie> cookies = options.Cookies.AllCookies;
Assert.That(cookies, Does.Contain(cookie), "Valid cookie was not returned");
}
[Test]
public void ShouldNotShowCookieAddedToDifferentDomain()
{
if (!CheckIsOnValidHostNameForCookieTests())
{
Assert.Ignore("Not on a standard domain for cookies (localhost doesn't count).");
}
driver.Url = macbethPage;
IOptions options = driver.Manage();
Cookie cookie = new Cookie("Bart", "Simpson", EnvironmentManager.Instance.UrlBuilder.HostName + ".com", EnvironmentManager.Instance.UrlBuilder.Path, null);
Assert.That(
() => options.Cookies.AddCookie(cookie),
Throws.InstanceOf<WebDriverException>().Or.InstanceOf<InvalidOperationException>());
ReadOnlyCollection<Cookie> cookies = options.Cookies.AllCookies;
Assert.That(cookies, Does.Not.Contain(cookie), "Invalid cookie was returned");
}
[Test]
public void ShouldNotShowCookieAddedToDifferentPath()
{
if (!CheckIsOnValidHostNameForCookieTests())
{
return;
}
// Cookies cannot be set on domain names with less than 2 dots, so
// localhost is out. If we are in that boat, bail the test.
string hostName = EnvironmentManager.Instance.UrlBuilder.HostName;
string[] hostNameParts = hostName.Split(new char[] { '.' });
if (hostNameParts.Length < 3)
{
Assert.Ignore("Skipping test: Cookies can only be set on fully-qualified domain names.");
}
driver.Url = macbethPage;
IOptions options = driver.Manage();
Cookie cookie = new Cookie("Lisa", "Simpson", EnvironmentManager.Instance.UrlBuilder.HostName, "/" + EnvironmentManager.Instance.UrlBuilder.Path + "IDoNotExist", null);
options.Cookies.AddCookie(cookie);
ReadOnlyCollection<Cookie> cookies = options.Cookies.AllCookies;
Assert.That(cookies, Does.Not.Contain(cookie), "Invalid cookie was returned");
}
[Test]
public void ShouldThrowExceptionWhenAddingCookieToCookieAverseDocument()
{
if (!CheckIsOnValidHostNameForCookieTests())
{
return;
}
// URLs using a non-network scheme (like "about:" or "data:") are
// averse to cookies, and should throw an InvalidCookieDomainException.
driver.Url = "about:blank";
IOptions options = driver.Manage();
Cookie cookie = new Cookie("question", "dunno");
Assert.That(
() => options.Cookies.AddCookie(cookie),
Throws.InstanceOf<InvalidCookieDomainException>().Or.InstanceOf<InvalidOperationException>());
}
[Test]
public void ShouldReturnNullBecauseCookieRetainsExpiry()
{
if (!CheckIsOnValidHostNameForCookieTests())
{
return;
}
Cookie addCookie = new Cookie("fish", "cod", "/common/animals", DateTime.Now.AddHours(-1));
IOptions options = driver.Manage();
options.Cookies.AddCookie(addCookie);
Cookie retrieved = options.Cookies.GetCookieNamed("fish");
Assert.That(retrieved, Is.Null);
}
[Test]
public void ShouldAddCookieToCurrentDomain()
{
if (!CheckIsOnValidHostNameForCookieTests())
{
return;
}
driver.Url = macbethPage;
IOptions options = driver.Manage();
Cookie cookie = new Cookie("Marge", "Simpson", "/");
options.Cookies.AddCookie(cookie);
ReadOnlyCollection<Cookie> cookies = options.Cookies.AllCookies;
Assert.That(cookies, Does.Contain(cookie), "Valid cookie was not returned");
}
[Test]
public void ShouldDeleteCookie()
{
if (!CheckIsOnValidHostNameForCookieTests())
{
return;
}
driver.Url = macbethPage;
IOptions options = driver.Manage();
Cookie cookieToDelete = new Cookie("answer", "42");
Cookie cookieToKeep = new Cookie("canIHaz", "Cheeseburguer");
options.Cookies.AddCookie(cookieToDelete);
options.Cookies.AddCookie(cookieToKeep);
ReadOnlyCollection<Cookie> cookies = options.Cookies.AllCookies;
options.Cookies.DeleteCookie(cookieToDelete);
ReadOnlyCollection<Cookie> cookies2 = options.Cookies.AllCookies;
Assert.That(cookies2, Does.Not.Contain(cookieToDelete), "Cookie was not deleted successfully");
Assert.That(cookies2, Does.Contain(cookieToKeep), "Valid cookie was not returned");
}
//////////////////////////////////////////////
// Support functions
//////////////////////////////////////////////
private void GotoValidDomainAndClearCookies(string page)
{
this.hostname = null;
String hostname = EnvironmentManager.Instance.UrlBuilder.HostName;
if (IsValidHostNameForCookieTests(hostname))
{
this.isOnAlternativeHostName = false;
this.hostname = hostname;
}
hostname = EnvironmentManager.Instance.UrlBuilder.AlternateHostName;
if (this.hostname == null && IsValidHostNameForCookieTests(hostname))
{
this.isOnAlternativeHostName = true;
this.hostname = hostname;
}
GoToPage(page);
driver.Manage().Cookies.DeleteAllCookies();
if (driver.Manage().Cookies.AllCookies.Count != 0)
{
// If cookies are still present, restart the driver and try again.
// This may mask some errors, where DeleteAllCookies doesn't fully
// delete all it should, but that's a tradeoff we need to be willing
// to make.
driver = EnvironmentManager.Instance.CreateFreshDriver();
GoToPage(page);
}
}
private bool CheckIsOnValidHostNameForCookieTests()
{
bool correct = this.hostname != null && IsValidHostNameForCookieTests(this.hostname);
if (!correct)
{
System.Console.WriteLine("Skipping test: unable to find domain name to use");
}
return correct;
}
private void GoToPage(String pageName)
{
driver.Url = this.isOnAlternativeHostName ? EnvironmentManager.Instance.UrlBuilder.WhereElseIs(pageName) : EnvironmentManager.Instance.UrlBuilder.WhereIs(pageName);
}
private void GoToOtherPage(String pageName)
{
driver.Url = this.isOnAlternativeHostName ? EnvironmentManager.Instance.UrlBuilder.WhereIs(pageName) : EnvironmentManager.Instance.UrlBuilder.WhereElseIs(pageName);
}
private bool IsValidHostNameForCookieTests(string hostname)
{
// TODO(JimEvan): Some coverage is better than none, so we
// need to ignore the fact that localhost cookies are problematic.
// Re-enable this when we have a better solution per DanielWagnerHall.
// ChromeDriver2 has trouble with localhost. IE and Firefox don't.
// return !IsIpv4Address(hostname) && "localhost" != hostname;
bool isLocalHostOkay = !("localhost" == hostname && !TestUtilities.IsInternetExplorer(driver));
return !IsIpv4Address(hostname) && isLocalHostOkay;
}
private static bool IsIpv4Address(string addrString)
{
return Regex.IsMatch(addrString, "\\d{1,3}(?:\\.\\d{1,3}){3}");
}
private string GenerateUniqueKey()
{
return string.Format("key_{0}", random.Next());
}
private string GetDocumentCookieOrNull()
{
IJavaScriptExecutor jsDriver = driver as IJavaScriptExecutor;
if (jsDriver == null)
{
return null;
}
try
{
return (string)jsDriver.ExecuteScript("return document.cookie");
}
catch (InvalidOperationException)
{
return null;
}
}
private void AssertNoCookiesArePresent()
{
Assert.That(driver.Manage().Cookies.AllCookies, Is.Empty, "Cookies were not empty");
string documentCookie = GetDocumentCookieOrNull();
if (documentCookie != null)
{
Assert.That(documentCookie, Is.Empty, "Cookies were not empty");
}
}
private void AssertSomeCookiesArePresent()
{
Assert.That(driver.Manage().Cookies.AllCookies, Is.Not.Empty, "Cookies were empty");
String documentCookie = GetDocumentCookieOrNull();
if (documentCookie != null)
{
Assert.That(documentCookie, Is.Not.Empty, "Cookies were empty");
}
}
private void AssertCookieIsNotPresentWithName(string key)
{
Assert.That(driver.Manage().Cookies.GetCookieNamed(key), Is.Null, "Cookie was present with name " + key);
string documentCookie = GetDocumentCookieOrNull();
if (documentCookie != null)
{
Assert.That(documentCookie, Does.Not.Contain(key + "="));
}
}
private void AssertCookieIsPresentWithName(string key)
{
Assert.That(driver.Manage().Cookies.GetCookieNamed(key), Is.Not.Null, "Cookie was present with name " + key);
string documentCookie = GetDocumentCookieOrNull();
if (documentCookie != null)
{
Assert.That(documentCookie, Does.Contain(key + "="));
}
}
private void AssertCookieHasValue(string key, string value)
{
Assert.That(driver.Manage().Cookies.GetCookieNamed(key).Value, Is.EqualTo(value), "Cookie had wrong value");
string documentCookie = GetDocumentCookieOrNull();
if (documentCookie != null)
{
Assert.That(documentCookie, Does.Contain(key + "=" + value));
}
}
private DateTime GetTimeInTheFuture()
{
return DateTime.Now.Add(TimeSpan.FromMilliseconds(100000));
}
}