omegafox/tests/async/test_browsercontext_add_cookies.py
daijro 68216153f3 Add Playwright tests
Adds Playwright's async tests to ensure that functionality is not broken.
2024-11-03 06:14:39 -06:00

413 lines
13 KiB
Python

# 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
from typing import Callable, List
import pytest
from playwright.async_api import Browser, BrowserContext, Error, Page
from tests.server import Server, TestServerRequest
from tests.utils import must
async def test_should_work(context: BrowserContext, page: Page, server: Server) -> None:
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: BrowserContext, page: Page, server: Server) -> None:
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() == []
# TODO: We are waiting for PEP705 so SetCookieParam can be readonly and matches the Cookie type.
await context.add_cookies(cookies) # type: ignore
assert await context.cookies() == cookies
async def test_should_send_cookie_header(server: Server, context: BrowserContext) -> None:
cookie: List[str] = []
def handler(request: TestServerRequest) -> None:
cookie.extend(must(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: BrowserContext, server: Server, browser: Browser
) -> None:
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: BrowserContext, server: Server, browser: Browser
) -> None:
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: BrowserContext, server: Server, browser: Browser
) -> None:
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: Server, context: BrowserContext, browser: Browser
) -> None:
cookie: List[str] = []
def handler(request: TestServerRequest) -> None:
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: Callable[..., "asyncio.Future[Browser]"], server: Server
) -> None:
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: BrowserContext, page: Page, server: Server
) -> None:
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: BrowserContext, server: Server
) -> None:
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: BrowserContext,
server: Server,
default_same_site_cookie_value: str,
) -> None:
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": default_same_site_cookie_value,
}
]
async def test_should_set_a_cookie_with_a_path(
context: BrowserContext,
page: Page,
server: Server,
default_same_site_cookie_value: str,
) -> None:
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": default_same_site_cookie_value,
}
]
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: BrowserContext, server: Server
) -> None:
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: BrowserContext,
) -> None:
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: BrowserContext, page: Page, server: Server
) -> None:
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: BrowserContext, page: Page, server: Server
) -> None:
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: BrowserContext,
page: Page,
server: Server,
default_same_site_cookie_value: str,
) -> None:
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": default_same_site_cookie_value,
}
]
async def test_should_set_cookies_for_a_frame(
context: BrowserContext, page: Page, server: Server
) -> None:
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: BrowserContext,
page: Page,
server: Server,
is_chromium: bool,
is_firefox: bool,
) -> None:
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_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": "Lax" if is_chromium else "None",
"secure": False,
"value": "John Doe",
}
]
else:
assert cookies == []