0
# API Testing
1
2
HTTP client for testing REST APIs and web services with request/response handling, authentication, and browser context integration.
3
4
## Capabilities
5
6
### API Request Context
7
8
HTTP client for making API requests independently or integrated with browser sessions.
9
10
```python { .api }
11
class APIRequest:
12
def new_context(
13
self,
14
base_url: Optional[str] = None,
15
extra_http_headers: Optional[Dict[str, str]] = None,
16
http_credentials: Optional[HttpCredentials] = None,
17
ignore_https_errors: Optional[bool] = None,
18
proxy: Optional[ProxySettings] = None,
19
user_agent: Optional[str] = None,
20
timeout: Optional[float] = None,
21
storage_state: Union[str, StorageState, None] = None
22
) -> APIRequestContext:
23
"""
24
Create API request context.
25
26
Args:
27
base_url: Base URL for relative requests
28
extra_http_headers: Default headers for all requests
29
http_credentials: HTTP authentication credentials
30
ignore_https_errors: Ignore SSL certificate errors
31
proxy: Proxy settings
32
user_agent: User agent string
33
timeout: Default timeout for requests
34
storage_state: Browser storage state for authentication
35
36
Returns:
37
APIRequestContext: HTTP client context
38
"""
39
40
class APIRequestContext:
41
"""HTTP client for API testing."""
42
43
def get(
44
self,
45
url: str,
46
params: Optional[Dict[str, Any]] = None,
47
headers: Optional[Dict[str, str]] = None,
48
timeout: Optional[float] = None,
49
fail_on_status_code: Optional[bool] = None,
50
ignore_https_errors: Optional[bool] = None
51
) -> APIResponse:
52
"""
53
Send GET request.
54
55
Args:
56
url: Request URL
57
params: Query parameters
58
headers: Request headers
59
timeout: Request timeout
60
fail_on_status_code: Throw on non-2xx status
61
ignore_https_errors: Ignore SSL errors
62
63
Returns:
64
APIResponse: HTTP response
65
"""
66
67
def post(
68
self,
69
url: str,
70
data: Optional[Union[str, bytes, Any]] = None,
71
params: Optional[Dict[str, Any]] = None,
72
headers: Optional[Dict[str, str]] = None,
73
form: Optional[Dict[str, Any]] = None,
74
multipart: Optional[Dict[str, Any]] = None,
75
timeout: Optional[float] = None,
76
fail_on_status_code: Optional[bool] = None,
77
ignore_https_errors: Optional[bool] = None
78
) -> APIResponse:
79
"""Send POST request with data, form, or multipart body."""
80
81
def put(
82
self,
83
url: str,
84
data: Optional[Union[str, bytes, Any]] = None,
85
params: Optional[Dict[str, Any]] = None,
86
headers: Optional[Dict[str, str]] = None,
87
form: Optional[Dict[str, Any]] = None,
88
multipart: Optional[Dict[str, Any]] = None,
89
timeout: Optional[float] = None,
90
fail_on_status_code: Optional[bool] = None,
91
ignore_https_errors: Optional[bool] = None
92
) -> APIResponse:
93
"""Send PUT request."""
94
95
def patch(
96
self,
97
url: str,
98
data: Optional[Union[str, bytes, Any]] = None,
99
params: Optional[Dict[str, Any]] = None,
100
headers: Optional[Dict[str, str]] = None,
101
form: Optional[Dict[str, Any]] = None,
102
multipart: Optional[Dict[str, Any]] = None,
103
timeout: Optional[float] = None,
104
fail_on_status_code: Optional[bool] = None,
105
ignore_https_errors: Optional[bool] = None
106
) -> APIResponse:
107
"""Send PATCH request."""
108
109
def delete(
110
self,
111
url: str,
112
params: Optional[Dict[str, Any]] = None,
113
headers: Optional[Dict[str, str]] = None,
114
timeout: Optional[float] = None,
115
fail_on_status_code: Optional[bool] = None,
116
ignore_https_errors: Optional[bool] = None
117
) -> APIResponse:
118
"""Send DELETE request."""
119
120
def head(
121
self,
122
url: str,
123
params: Optional[Dict[str, Any]] = None,
124
headers: Optional[Dict[str, str]] = None,
125
timeout: Optional[float] = None,
126
fail_on_status_code: Optional[bool] = None,
127
ignore_https_errors: Optional[bool] = None
128
) -> APIResponse:
129
"""Send HEAD request."""
130
131
def fetch(
132
self,
133
url_or_request: Union[str, Request],
134
params: Optional[Dict[str, Any]] = None,
135
headers: Optional[Dict[str, str]] = None,
136
data: Optional[Union[str, bytes, Any]] = None,
137
form: Optional[Dict[str, Any]] = None,
138
multipart: Optional[Dict[str, Any]] = None,
139
method: Optional[str] = None,
140
timeout: Optional[float] = None,
141
fail_on_status_code: Optional[bool] = None,
142
ignore_https_errors: Optional[bool] = None
143
) -> APIResponse:
144
"""Send custom HTTP request."""
145
146
def storage_state(self, path: Optional[str] = None) -> StorageState:
147
"""Get current storage state for session persistence."""
148
149
def dispose(self) -> None:
150
"""Clean up API request context."""
151
```
152
153
### API Response
154
155
HTTP response object with data access methods.
156
157
```python { .api }
158
class APIResponse:
159
"""HTTP response from API request."""
160
url: str
161
ok: bool
162
status: int
163
status_text: str
164
headers: Dict[str, str]
165
166
def body(self) -> bytes:
167
"""Get response body as bytes."""
168
169
def text(self) -> str:
170
"""Get response body as text."""
171
172
def json(self) -> Any:
173
"""Parse response body as JSON."""
174
175
def header_value(self, name: str) -> Optional[str]:
176
"""Get specific header value."""
177
178
def headers_array(self) -> List[Dict[str, str]]:
179
"""Get headers as array of name-value pairs."""
180
181
def dispose(self) -> None:
182
"""Clean up response resources."""
183
```
184
185
## Usage Examples
186
187
### Basic API Testing
188
189
```python
190
from playwright.sync_api import sync_playwright, expect
191
192
with sync_playwright() as p:
193
# Create API context
194
request_context = p.request.new_context(
195
base_url="https://api.example.com",
196
extra_http_headers={"Authorization": "Bearer token123"}
197
)
198
199
# GET request
200
response = request_context.get("/users")
201
expect(response).to_be_ok()
202
203
users = response.json()
204
assert len(users) > 0
205
206
# POST request
207
new_user = {
208
"name": "John Doe",
209
"email": "john@example.com"
210
}
211
212
response = request_context.post("/users", data=new_user)
213
expect(response).to_be_ok()
214
215
created_user = response.json()
216
assert created_user["id"] is not None
217
218
request_context.dispose()
219
```
220
221
### API Testing with Browser Context
222
223
```python
224
with sync_playwright() as p:
225
browser = p.chromium.launch()
226
context = browser.new_context()
227
page = context.new_page()
228
229
# Login through browser
230
page.goto("https://app.example.com/login")
231
page.fill("#username", "testuser")
232
page.fill("#password", "password")
233
page.click("#login-btn")
234
235
# Use browser's authentication for API calls
236
storage_state = context.storage_state()
237
238
api_context = p.request.new_context(
239
base_url="https://api.example.com",
240
storage_state=storage_state
241
)
242
243
# API calls now authenticated
244
response = api_context.get("/profile")
245
expect(response).to_be_ok()
246
247
profile = response.json()
248
assert profile["username"] == "testuser"
249
250
api_context.dispose()
251
browser.close()
252
```
253
254
### File Upload via API
255
256
```python
257
with sync_playwright() as p:
258
api_context = p.request.new_context(
259
base_url="https://api.example.com"
260
)
261
262
# Upload file with multipart data
263
response = api_context.post("/upload", multipart={
264
"file": {
265
"name": "document.pdf",
266
"mimeType": "application/pdf",
267
"buffer": open("document.pdf", "rb").read()
268
},
269
"description": "Important document"
270
})
271
272
expect(response).to_be_ok()
273
274
upload_result = response.json()
275
assert upload_result["file_id"] is not None
276
277
api_context.dispose()
278
```