# Copyright (c) Microsoft Corporation.
#
# Licensed 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.
import asyncio
import datetime
import pytest
from playwright.async_api import Error
async def test_should_work(context, page, server):
await page.goto(server.EMPTY_PAGE)
await context.add_cookies(
[{"url": server.EMPTY_PAGE, "name": "password", "value": "123456"}]
)
assert await page.evaluate("() => document.cookie") == "password=123456"
async def test_should_roundtrip_cookie(context, page, server):
await page.goto(server.EMPTY_PAGE)
# @see https://en.wikipedia.org/wiki/Year_2038_problem
date = int(datetime.datetime(2038, 1, 1).timestamp() * 1000)
document_cookie = await page.evaluate(
"""timestamp => {
const date = new Date(timestamp);
document.cookie = `username=John Doe;expires=${date.toUTCString()}`;
return document.cookie;
}""",
date,
)
assert document_cookie == "username=John Doe"
cookies = await context.cookies()
await context.clear_cookies()
assert await context.cookies() == []
await context.add_cookies(cookies)
assert await context.cookies() == cookies
async def test_should_send_cookie_header(server, context):
cookie = []
def handler(request):
cookie.extend(request.requestHeaders.getRawHeaders("cookie"))
request.finish()
server.set_route("/empty.html", handler)
await context.add_cookies(
[{"url": server.EMPTY_PAGE, "name": "cookie", "value": "value"}]
)
page = await context.new_page()
await page.goto(server.EMPTY_PAGE)
assert cookie == ["cookie=value"]
async def test_should_isolate_cookies_in_browser_contexts(context, server, browser):
another_context = await browser.new_context()
await context.add_cookies(
[{"url": server.EMPTY_PAGE, "name": "isolatecookie", "value": "page1value"}]
)
await another_context.add_cookies(
[{"url": server.EMPTY_PAGE, "name": "isolatecookie", "value": "page2value"}]
)
cookies_1 = await context.cookies()
cookies_2 = await another_context.cookies()
assert len(cookies_1) == 1
assert len(cookies_2) == 1
assert cookies_1[0]["name"] == "isolatecookie"
assert cookies_1[0]["value"] == "page1value"
assert cookies_2[0]["name"] == "isolatecookie"
assert cookies_2[0]["value"] == "page2value"
await another_context.close()
async def test_should_isolate_session_cookies(context, server, browser):
server.set_route(
"/setcookie.html",
lambda r: (
r.setHeader("Set-Cookie", "session=value"),
r.finish(),
),
)
page_1 = await context.new_page()
await page_1.goto(server.PREFIX + "/setcookie.html")
##
page_2 = await context.new_page()
await page_2.goto(server.EMPTY_PAGE)
cookies_2 = await context.cookies()
assert len(cookies_2) == 1
assert ",".join(list(map(lambda c: c["value"], cookies_2))) == "value"
##
context_b = await browser.new_context()
page_3 = await context_b.new_page()
await page_3.goto(server.EMPTY_PAGE)
cookies_3 = await context_b.cookies()
assert cookies_3 == []
await context_b.close()
async def test_should_isolate_persistent_cookies(context, server, browser):
server.set_route(
"/setcookie.html",
lambda r: (
r.setHeader("Set-Cookie", "persistent=persistent-value; max-age=3600"),
r.finish(),
),
)
page = await context.new_page()
await page.goto(server.PREFIX + "/setcookie.html")
context_1 = context
context_2 = await browser.new_context()
[page_1, page_2] = await asyncio.gather(context_1.new_page(), context_2.new_page())
await asyncio.gather(page_1.goto(server.EMPTY_PAGE), page_2.goto(server.EMPTY_PAGE))
[cookies_1, cookies_2] = await asyncio.gather(
context_1.cookies(), context_2.cookies()
)
assert len(cookies_1) == 1
assert cookies_1[0]["name"] == "persistent"
assert cookies_1[0]["value"] == "persistent-value"
assert len(cookies_2) == 0
await context_2.close()
async def test_should_isolate_send_cookie_header(server, context, browser):
cookie = []
def handler(request):
cookie.extend(request.requestHeaders.getRawHeaders("cookie") or [])
request.finish()
server.set_route("/empty.html", handler)
await context.add_cookies(
[{"url": server.EMPTY_PAGE, "name": "sendcookie", "value": "value"}]
)
page_1 = await context.new_page()
await page_1.goto(server.EMPTY_PAGE)
assert cookie == ["sendcookie=value"]
cookie.clear()
##
context_2 = await browser.new_context()
page_2 = await context_2.new_page()
await page_2.goto(server.EMPTY_PAGE)
assert cookie == []
await context_2.close()
async def test_should_isolate_cookies_between_launches(browser_factory, server):
browser_1 = await browser_factory()
context_1 = await browser_1.new_context()
await context_1.add_cookies(
[
{
"url": server.EMPTY_PAGE,
"name": "cookie-in-context-1",
"value": "value",
"expires": int(datetime.datetime.now().timestamp() + 10000),
}
]
)
await browser_1.close()
browser_2 = await browser_factory()
context_2 = await browser_2.new_context()
cookies = await context_2.cookies()
assert cookies == []
await browser_2.close()
async def test_should_set_multiple_cookies(context, page, server):
await page.goto(server.EMPTY_PAGE)
await context.add_cookies(
[
{"url": server.EMPTY_PAGE, "name": "multiple-1", "value": "123456"},
{"url": server.EMPTY_PAGE, "name": "multiple-2", "value": "bar"},
]
)
assert (
await page.evaluate(
"""() => {
const cookies = document.cookie.split(';');
return cookies.map(cookie => cookie.trim()).sort();
}"""
)
== ["multiple-1=123456", "multiple-2=bar"]
)
async def test_should_have_expires_set_to_neg_1_for_session_cookies(context, server):
await context.add_cookies(
[{"url": server.EMPTY_PAGE, "name": "expires", "value": "123456"}]
)
cookies = await context.cookies()
assert cookies[0]["expires"] == -1
async def test_should_set_cookie_with_reasonable_defaults(context, server):
await context.add_cookies(
[{"url": server.EMPTY_PAGE, "name": "defaults", "value": "123456"}]
)
cookies = await context.cookies()
cookies.sort(key=lambda r: r["name"])
assert cookies == [
{
"name": "defaults",
"value": "123456",
"domain": "localhost",
"path": "/",
"expires": -1,
"httpOnly": False,
"secure": False,
"sameSite": "None",
}
]
async def test_should_set_a_cookie_with_a_path(context, page, server):
await page.goto(server.PREFIX + "/grid.html")
await context.add_cookies(
[
{
"domain": "localhost",
"path": "/grid.html",
"name": "gridcookie",
"value": "GRID",
}
]
)
assert await context.cookies() == [
{
"name": "gridcookie",
"value": "GRID",
"domain": "localhost",
"path": "/grid.html",
"expires": -1,
"httpOnly": False,
"secure": False,
"sameSite": "None",
}
]
assert await page.evaluate("document.cookie") == "gridcookie=GRID"
await page.goto(server.EMPTY_PAGE)
assert await page.evaluate("document.cookie") == ""
await page.goto(server.PREFIX + "/grid.html")
assert await page.evaluate("document.cookie") == "gridcookie=GRID"
async def test_should_not_set_a_cookie_with_blank_page_url(context, server):
with pytest.raises(Error) as exc_info:
await context.add_cookies(
[
{"url": server.EMPTY_PAGE, "name": "example-cookie", "value": "best"},
{"url": "about:blank", "name": "example-cookie-blank", "value": "best"},
]
)
assert (
'Blank page can not have cookie "example-cookie-blank"'
in exc_info.value.message
)
async def test_should_not_set_a_cookie_on_a_data_url_page(context):
with pytest.raises(Error) as exc_info:
await context.add_cookies(
[
{
"url": "data:,Hello%2C%20World!",
"name": "example-cookie",
"value": "best",
}
]
)
assert (
'Data URL page can not have cookie "example-cookie"' in exc_info.value.message
)
async def test_should_default_to_setting_secure_cookie_for_https_websites(
context, page, server
):
await page.goto(server.EMPTY_PAGE)
SECURE_URL = "https://example.com"
await context.add_cookies([{"url": SECURE_URL, "name": "foo", "value": "bar"}])
[cookie] = await context.cookies(SECURE_URL)
assert cookie["secure"]
async def test_should_be_able_to_set_unsecure_cookie_for_http_website(
context, page, server
):
await page.goto(server.EMPTY_PAGE)
HTTP_URL = "http://example.com"
await context.add_cookies([{"url": HTTP_URL, "name": "foo", "value": "bar"}])
[cookie] = await context.cookies(HTTP_URL)
assert not cookie["secure"]
async def test_should_set_a_cookie_on_a_different_domain(context, page, server):
await page.goto(server.EMPTY_PAGE)
await context.add_cookies(
[{"url": "https://www.example.com", "name": "example-cookie", "value": "best"}]
)
assert await page.evaluate("document.cookie") == ""
assert await context.cookies("https://www.example.com") == [
{
"name": "example-cookie",
"value": "best",
"domain": "www.example.com",
"path": "/",
"expires": -1,
"httpOnly": False,
"secure": True,
"sameSite": "None",
}
]
async def test_should_set_cookies_for_a_frame(context, page, server):
await page.goto(server.EMPTY_PAGE)
await context.add_cookies(
[{"url": server.PREFIX, "name": "frame-cookie", "value": "value"}]
)
await page.evaluate(
"""src => {
let fulfill;
const promise = new Promise(x => fulfill = x);
const iframe = document.createElement('iframe');
document.body.appendChild(iframe);
iframe.onload = fulfill;
iframe.src = src;
return promise;
}""",
server.PREFIX + "/grid.html",
)
assert await page.frames[1].evaluate("document.cookie") == "frame-cookie=value"
async def test_should_not_block_third_party_cookies(
context, page, server, is_chromium, is_firefox
):
await page.goto(server.EMPTY_PAGE)
await page.evaluate(
"""src => {
let fulfill;
const promise = new Promise(x => fulfill = x);
const iframe = document.createElement('iframe');
document.body.appendChild(iframe);
iframe.onload = fulfill;
iframe.src = src;
return promise;
}""",
server.CROSS_PROCESS_PREFIX + "/grid.html",
)
await page.frames[1].evaluate("document.cookie = 'username=John Doe'")
await page.wait_for_timeout(2000)
allows_third_party = is_chromium or is_firefox
cookies = await context.cookies(server.CROSS_PROCESS_PREFIX + "/grid.html")
if allows_third_party:
assert cookies == [
{
"domain": "127.0.0.1",
"expires": -1,
"httpOnly": False,
"name": "username",
"path": "/",
"sameSite": "None",
"secure": False,
"value": "John Doe",
}
]
else:
assert cookies == []