2014-03-19 58 views
5

我有一個關於硒的代碼來測試一個表單。但是,首先我轉到另一頁,然後重定向到我的頁面。當我設置cookie來新的領域,我得到錯誤:硒餅乾與另一個域

Exception in thread "main" org.openqa.selenium.InvalidCookieDomainException: You may only set cookies for the current domain 

我的代碼:

//it is going to example.com and example redirect me to the "example.com" all cookie domains is "example.com" 
driver.get("http://www.example.com?id=1"); 

Set<Cookie> cookies = driver.manage().getCookies(); 
Iterator<Cookie> itr = cookies.iterator(); 

    while (itr.hasNext()){ 
    Cookie c = itr.next(); 
    System.out.println("Cookie Name: " + c.getName() + " --- " + "Cookie Domain: " + c.getDomain() + " --- " + "Cookie Value: " + c.getValue()); 

    driver.manage().addCookie(c); 
    } 

如何管理的?我必須爲example.com獲取/設置cookie

+1

根據錯誤:'你只能爲當前域設置Cookie'你不能那樣做。 – sircapsalot

回答

6

爲什麼不在添加cookie之前將瀏覽器重定向到「example.com」。進入該域後,添加您從「example.com」獲取的cookie值並刷新頁面?

按照the answer by the team on this issue的項目跟蹤,

The cookies methods only act on cookies that would be visible as this is the only thing that can be made to work consistently across all browsers. The behaviour that you see is the expected behaviour.

+0

Thanks anotherdave –

+1

你必須做一整頁加載來設置一個cookie,這是相當荒謬的。如果您在多個域中都有Cookie,則必須爲每個域進行頁面加載。 – speedplane

+0

@speedplane:對於寫Selenium的人來說公平,我不會稱之爲荒謬的 - 假設有很多個人瀏覽器的特質,他們必須努力工作。如果您的需求涉及更多,您可以隨時在您的測試套件之外進行設置 - 例如創建一個[預先配置了Cookie的Firefox配置文件](https://support.mozilla.org/en-US/questions/1096646)或將一個cookie文件傳遞給PhantomJS等。 – anotherdave

0

像以前的答案,這是預期的行爲提及。

到目前爲止唯一的工作是到driver.get("domain.com/404")頁面。但是,這並不總是因爲工作經常SSO保護domain.com/*

我已經對規範中的一個新的功能要求:https://github.com/w3c/webdriver/issues/1238

使它所以404工作周圍總能工作。

The webdriver spec https://w3c.github.io/webdriver/webdriver-spec.html#add-cookie forces the current browser session to be on the domain where you are adding the cookie to.

This makes tons of sense and I agree with it.

This unfortunately prevents 2 key use cases:

You want to re-use cookies from another webdriver session in a new session to avoid repeating the work it took to get the cookies. Such as having to repeat a login. Allow a webdriver pool to be shared amongst unrelated threads where each thread might have their own cookies. The only current work around is to attempt to force the webdriver to go to a 404 error page with something like: webdriver.get(" http://the-cookie-domain.com/404adsfasdf "). This would cause the page to go to domain and would allow you to add cookies with addCookie. But this hardly ever works. Because the page is very often protected by SSO, any attempt to go to http://the-cookie-domain.com/ * sends you to an SSO login page e.g. http://login.ssodomain.com and now you have the same problem.

We should add a new method to the spec webdriver.goTo404Page(domain) to allow this use-case. This method should simulate a 404 HTTP status code response from domain in the browser.

Alternatively maybe be a new overload to addCookie could allow this, for example: void addCookie(Cookie var1, String goTo404PageOfDomain);

By allowing users to go to a fake 404 page of any given domain, this guarantees the 404-page workaround works for any page and these 2 use cases are now possible.

對於firefox,您可以稍微修改Marionette以刪除此檢查。

diff --git a/testing/marionette/cookie.js b/testing/marionette/cookie.js 
--- a/testing/marionette/cookie.js 
+++ b/testing/marionette/cookie.js 
@@ -144,14 +144,14 @@ cookie.add = function(newCookie, {restri 
    newCookie.domain = "." + newCookie.domain; 
    } 

- if (restrictToHost) { 
- if (!restrictToHost.endsWith(newCookie.domain) && 
-  ("." + restrictToHost) !== newCookie.domain && 
-  restrictToHost !== newCookie.domain) { 
-  throw new InvalidCookieDomainError(`Cookies may only be set ` + 
-   `for the current domain (${restrictToHost})`); 
- } 
- } 
+// if (restrictToHost) { 
+// if (!restrictToHost.endsWith(newCookie.domain) && 
+//  ("." + restrictToHost) !== newCookie.domain && 
+//  restrictToHost !== newCookie.domain) { 
+//  throw new InvalidCookieDomainError(`Cookies may only be set ` + 
+//   `for the current domain (${restrictToHost})`); 
+// } 
+// } 

    // remove port from domain, if present. 
    // unfortunately this catches IPv6 addresses by mistake 
diff --git a/testing/marionette/driver.js b/testing/marionette/driver.js 
--- a/testing/marionette/driver.js 
+++ b/testing/marionette/driver.js 
@@ -2638,9 +2638,9 @@ GeckoDriver.prototype.addCookie = functi 
    let {protocol, hostname} = this.currentURL; 

    const networkSchemes = ["ftp:", "http:", "https:"]; 
- if (!networkSchemes.includes(protocol)) { 
- throw new InvalidCookieDomainError("Document is cookie-averse"); 
- } 
+// if (!networkSchemes.includes(protocol)) { 
+// throw new InvalidCookieDomainError("Document is cookie-averse"); 
+// } 

    let newCookie = cookie.fromJSON(cmd.parameters.cookie); 

diff --git a/testing/marionette/test_cookie.js b/testing/marionette/test_cookie.js 
--- a/testing/marionette/test_cookie.js 
+++ b/testing/marionette/test_cookie.js 
@@ -190,10 +190,10 @@ add_test(function test_add() { 
    }); 
    equal(2, cookie.manager.cookies.length); 

- Assert.throws(() => { 
- let biscuit = {name: "name3", value: "value3", domain: "domain3"}; 
- cookie.add(biscuit, {restrictToHost: "other domain"}); 
- }, /Cookies may only be set for the current domain/); 
+// Assert.throws(() => { 
+// let biscuit = {name: "name3", value: "value3", domain: "domain3"}; 
+// cookie.add(biscuit, {restrictToHost: "other domain"}); 
+// }, /Cookies may only be set for the current domain/); 

    cookie.add({ 
    name: "name4",