Path: blob/trunk/dotnet/test/common/CookieImplementationTest.cs
2868 views
// <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)); } }