Skip to content

Commit 510f2e9

Browse files
feat: allow for empty headers in network.setExtraHeaders (#3636)
Addressing w3c/webdriver-bidi#977. Spec: w3c/webdriver-bidi#978
1 parent 82cf39f commit 510f2e9

File tree

3 files changed

+157
-5
lines changed

3 files changed

+157
-5
lines changed

src/protocol-parser/generated/webdriver-bidi.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1904,7 +1904,7 @@ export namespace Network {
19041904
export namespace Network {
19051905
export const SetExtraHeadersParametersSchema = z.lazy(() =>
19061906
z.object({
1907-
headers: z.array(Network.HeaderSchema).min(1),
1907+
headers: z.array(Network.HeaderSchema),
19081908
contexts: z
19091909
.array(BrowsingContext.BrowsingContextSchema)
19101910
.min(1)

src/protocol/generated/webdriver-bidi.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1559,7 +1559,7 @@ export namespace Network {
15591559
}
15601560
export namespace Network {
15611561
export type SetExtraHeadersParameters = {
1562-
headers: [Network.Header, ...Network.Header[]];
1562+
headers: [...Network.Header[]];
15631563
contexts?: [
15641564
BrowsingContext.BrowsingContext,
15651565
...BrowsingContext.BrowsingContext[],

tests/network/test_set_extra_headers.py

Lines changed: 155 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
SOME_HEADER_VALUE = 'SOME HEADER VALUE'
2424
ANOTHER_HEADER_NAME = 'Another-Header-Name'
2525
ANOTHER_HEADER_VALUE = 'ANOTHER HEADER VALUE'
26+
REFERER_HEADER_NAME = "Referer"
27+
REFERER_HEADER_VALUE = "http://google.com/"
2628

2729

2830
@pytest_asyncio.fixture
@@ -74,10 +76,11 @@ async def _assert_headers(context_id,
7476
headers = await get_headers(context_id, same_origin)
7577
for key, value in expected_headers.items():
7678
if value is None:
77-
assert key not in headers
79+
assert key not in headers, f"'{key}' header should not be present in the request headers"
7880
else:
79-
assert key in headers
80-
assert headers[key] == value
81+
assert key in headers, f"'{key}' header should be present in the request headers"
82+
assert headers[
83+
key] == value, f"'{key}' header should have value of '{value}'"
8184

8285
return _assert_headers
8386

@@ -121,6 +124,19 @@ async def test_network_set_extra_headers_global(websocket, context_id, setup,
121124
SOME_HEADER_NAME: None
122125
})
123126

127+
# Clear headers.
128+
await execute_command(websocket, {
129+
"method": "network.setExtraHeaders",
130+
"params": {
131+
"headers": [],
132+
}
133+
})
134+
await assert_headers(context_id,
135+
expected_headers={
136+
ANOTHER_HEADER_NAME: None,
137+
SOME_HEADER_NAME: None
138+
})
139+
124140

125141
@pytest.mark.asyncio
126142
async def test_network_set_extra_headers_per_context(websocket, context_id,
@@ -176,6 +192,26 @@ async def test_network_set_extra_headers_per_context(websocket, context_id,
176192
SOME_HEADER_NAME: None
177193
})
178194

195+
# Clear headers for the first context.
196+
await execute_command(
197+
websocket, {
198+
"method": "network.setExtraHeaders",
199+
"params": {
200+
"contexts": [context_id],
201+
"headers": [],
202+
}
203+
})
204+
await assert_headers(context_id,
205+
expected_headers={
206+
SOME_HEADER_NAME: None,
207+
ANOTHER_HEADER_NAME: None
208+
})
209+
await assert_headers(another_context_id,
210+
expected_headers={
211+
ANOTHER_HEADER_NAME: ANOTHER_HEADER_VALUE,
212+
SOME_HEADER_NAME: None
213+
})
214+
179215

180216
@pytest.mark.asyncio
181217
async def test_network_set_extra_headers_per_user_context(
@@ -250,6 +286,26 @@ async def test_network_set_extra_headers_per_user_context(
250286
SOME_HEADER_NAME: None
251287
})
252288

289+
# Clear headers for the first user context.
290+
await execute_command(
291+
websocket, {
292+
"method": "network.setExtraHeaders",
293+
"params": {
294+
"userContexts": ["default"],
295+
"headers": [],
296+
}
297+
})
298+
await assert_headers(browsing_context_id_1,
299+
expected_headers={
300+
ANOTHER_HEADER_NAME: None,
301+
SOME_HEADER_NAME: None
302+
})
303+
await assert_headers(browsing_context_id_2,
304+
expected_headers={
305+
ANOTHER_HEADER_NAME: ANOTHER_HEADER_VALUE,
306+
SOME_HEADER_NAME: None
307+
})
308+
253309

254310
@pytest.mark.asyncio
255311
async def test_network_set_extra_headers_iframe(websocket, context_id,
@@ -301,6 +357,22 @@ async def test_network_set_extra_headers_iframe(websocket, context_id,
301357
},
302358
same_origin=False)
303359

360+
# Clear headers.
361+
await execute_command(
362+
websocket, {
363+
"method": "network.setExtraHeaders",
364+
"params": {
365+
"contexts": [context_id],
366+
"headers": [],
367+
}
368+
})
369+
await assert_headers(iframe_id,
370+
expected_headers={
371+
ANOTHER_HEADER_NAME: None,
372+
SOME_HEADER_NAME: None
373+
},
374+
same_origin=False)
375+
304376

305377
@pytest.mark.asyncio
306378
async def test_network_set_extra_headers_invalid_value(websocket, context_id,
@@ -324,3 +396,83 @@ async def test_network_set_extra_headers_invalid_value(websocket, context_id,
324396
}],
325397
}
326398
})
399+
400+
401+
@pytest.mark.asyncio
402+
async def test_network_set_extra_headers_referer_with_fetch(
403+
websocket, context_id, setup, assert_headers):
404+
await setup(context_id)
405+
await execute_command(
406+
websocket, {
407+
"method": "network.setExtraHeaders",
408+
"params": {
409+
"headers": [{
410+
'name': SOME_HEADER_NAME,
411+
'value': {
412+
'type': 'string',
413+
'value': SOME_HEADER_VALUE
414+
}
415+
}, {
416+
'name': REFERER_HEADER_NAME,
417+
'value': {
418+
'type': 'string',
419+
'value': REFERER_HEADER_VALUE
420+
}
421+
}],
422+
}
423+
})
424+
425+
await assert_headers(context_id,
426+
expected_headers={
427+
SOME_HEADER_NAME: SOME_HEADER_VALUE,
428+
REFERER_HEADER_NAME: REFERER_HEADER_VALUE
429+
})
430+
431+
432+
@pytest.mark.asyncio
433+
async def test_network_set_extra_headers_referer_with_navigation(
434+
websocket, context_id, url_echo):
435+
await execute_command(
436+
websocket, {
437+
"method": "network.setExtraHeaders",
438+
"params": {
439+
"headers": [{
440+
'name': SOME_HEADER_NAME,
441+
'value': {
442+
'type': 'string',
443+
'value': SOME_HEADER_VALUE
444+
}
445+
}, {
446+
'name': REFERER_HEADER_NAME,
447+
'value': {
448+
'type': 'string',
449+
'value': REFERER_HEADER_VALUE
450+
}
451+
}],
452+
}
453+
})
454+
455+
await goto_url(websocket, context_id, url_echo)
456+
457+
response = await execute_command(
458+
websocket, {
459+
'method': 'script.evaluate',
460+
'params': {
461+
'expression': "document.body.innerText",
462+
'awaitPromise': True,
463+
'target': {
464+
'context': context_id
465+
}
466+
}
467+
})
468+
469+
assert response['result']['value']
470+
request_data = JSONDecoder().decode(response['result']['value'])
471+
headers = request_data['headers']
472+
assert headers[SOME_HEADER_NAME] == SOME_HEADER_VALUE
473+
474+
pytest.xfail(
475+
"`Referer` headers is not set during navigation: https://github.com/GoogleChromeLabs/chromium-bidi/issues/3637"
476+
)
477+
assert REFERER_HEADER_NAME in headers, f"'{REFERER_HEADER_NAME}' header should be present in the request headers"
478+
assert headers[REFERER_HEADER_NAME] == REFERER_HEADER_VALUE

0 commit comments

Comments
 (0)