Playwrite using API
https://playwright.dev/python/docs/api-testing
Playwright can be used to get access to the REST API of your application.
test_api_testing.py
from enum import auto
import os
from typing import Generator
import pytest
from playwright.sync_api import Playwright, Page, APIRequestContext, expect
GITHUB_API_TOKEN = "TOKEN HERE" #https://github.com/settings/tokens
assert GITHUB_API_TOKEN, "GITHUB_API_TOKEN is not set"
GITHUB_USER = "RizwanKMW"
assert GITHUB_USER, "GITHUB_USER is not set"
GITHUB_REPO = "test"
@pytest.fixture(scope="session")
def api_request_context(
playwright: Playwright,
) -> Generator[APIRequestContext, None, None]:
headers = {
"Accept": "application/vnd.github.v3+json",
"Authorization": f"token {GITHUB_API_TOKEN}",
}
request_context = playwright.request.new_context(
base_url="https://api.github.com", extra_http_headers=headers
)
yield request_context
request_context.dispose()
@pytest.fixture(scope="session", autouse=True)
def create_test_repository(
api_request_context: APIRequestContext,
) -> Generator[None, None, None]:
#Before all
new_repo = api_request_context.post("/user/repos", data={"name": GITHUB_REPO})
if not new_repo.ok:
print(f"Failed to create repo: {new_repo.status} - {new_repo.text()}")
assert new_repo.ok
yield
#After all
deleted_repo = api_request_context.delete(f"/repos/{GITHUB_USER}/{GITHUB_REPO}")
if not deleted_repo.ok:
print(f"Failed to delete repo: {deleted_repo.status} - {deleted_repo.text()}")
assert deleted_repo.ok, f"Repository deletion failed: {deleted_repo.text()}"
def test_should_create_bug_report(api_request_context: APIRequestContext) -> None:
data = {
"title": "[Bug] report 1",
"body": "Bug description",
}
new_issue = api_request_context.post(
f"/repos/{GITHUB_USER}/{GITHUB_REPO}/issues", data=data
)
assert new_issue.ok
issues = api_request_context.get(f"/repos/{GITHUB_USER}/{GITHUB_REPO}/issues")
assert issues.ok
issues_response = issues.json()
issue = list(
filter(lambda issue: issue["title"] == "[Bug] report 1", issues_response)
)[0]
assert issue
assert issue["body"] == "Bug description"
def test_should_create_feature_request(api_request_context: APIRequestContext) -> None:
data = {
"title": "[Feature] request 1",
"body": "Feature description",
}
new_issue = api_request_context.post(
f"/repos/{GITHUB_USER}/{GITHUB_REPO}/issues", data=data
)
assert new_issue.ok
issues = api_request_context.get(f"/repos/{GITHUB_USER}/{GITHUB_REPO}/issues")
assert issues.ok
issues_response = issues.json()
issue = list(
filter(lambda issue: issue["title"] == "[Feature] request 1", issues_response)
)[0]
assert issue
assert issue["body"] == "Feature description"
One more testing: test_api_json_place
import pytest
from playwright.sync_api import Playwright, APIRequestContext, expect
from typing import Generator
# API base URL (assuming a mock API is running locally)
API_BASE_URL = "https://jsonplaceholder.typicode.com/"
# Fixture to set up API request context
@pytest.fixture(scope="session")
def api_request_context(
playwright: Playwright,
) -> Generator[APIRequestContext, None, None]:
"""Sets up a Playwright API request context for the session."""
request_context = playwright.request.new_context(
base_url=API_BASE_URL,
extra_http_headers={"Accept": "application/json"}
)
yield request_context
request_context.dispose()
# Test for /users endpoint
def test_users_endpoint(api_request_context: APIRequestContext) -> None:
"""Tests that the /users endpoint returns 10 users."""
response = api_request_context.get("/users")
assert response.ok, f"Request failed with status {response.status}"
users = response.json()
assert len(users) == 10, f"Expected 10 users, got {len(users)}"
# Check basic structure of a user
first_user = users[0]
assert "id" in first_user
assert "name" in first_user
# Test for /posts endpoint
def test_posts_endpoint(api_request_context: APIRequestContext) -> None:
"""Tests that the /posts endpoint returns 100 posts."""
response = api_request_context.get("/posts")
assert response.ok, f"Request failed with status {response.status}"
posts = response.json()
assert len(posts) == 100, f"Expected 100 posts, got {len(posts)}"
# Check basic structure of a post
first_post = posts[0]
assert "id" in first_post
assert "title" in first_post
print(first_post["title"])
# Test for /comments endpoint
def test_comments_endpoint(api_request_context: APIRequestContext) -> None:
"""Tests that the /comments endpoint returns 500 comments."""
response = api_request_context.get("/comments")
assert response.ok, f"Request failed with status {response.status}"
comments = response.json()
assert len(comments) == 500, f"Expected 500 comments, got {len(comments)}"
# Check basic structure of a comment
first_comment = comments[0]
assert "id" in first_comment
assert "email" in first_comment
print(first_comment["email"])
# Optional: Test relationships between endpoints
def test_data_relationships(api_request_context: APIRequestContext) -> None:
"""Tests that user_ids and post_ids in comments are valid."""
users_response = api_request_context.get("/users")
posts_response = api_request_context.get("/posts")
comments_response = api_request_context.get("/comments")
assert users_response.ok and posts_response.ok and comments_response.ok
users = users_response.json()
posts = posts_response.json()
comments = comments_response.json()
user_ids = {user["id"] for user in users} # Set of valid user IDs
post_ids = {post["id"] for post in posts} # Set of valid post IDs