blob: 8a7831d386ab05f60a4668a2d24ffac4922ed676 [file] [log] [blame]
// Copyright 2025 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// META script=resources/controlled_frame_helpers.js
// META script=resources/event_handler_helpers.js
// This file contains authrequired event related tests.
//
// Successful authentications are cached and can mess with subsequent tests.
// To get around this, the test uses separate partitions for tests that
// successfully authenticate, but a shared partition for others to speed up the
// tests because partition creation is expensive.
async function sleep(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
promise_test(async (test) => {
const controlledframe = await createControlledFrame('/simple.html', 'auth1');
controlledframe.stop();
const targetUrl = new URL(controlledframe.src);
targetUrl.pathname = '/auth-basic';
targetUrl.search = '*';
addWebRequestListeners(controlledframe, targetUrl.toString());
controlledframe.request.createWebRequestInterceptor({
urlPatterns: [targetUrl.toString()],
blocking: true,
}).addEventListener('authrequired', (e) => {
e.setCredentials(new Promise((resolve) => {
// Sleep to ensure the network request is paused until the
// promise resolves.
sleep(1);
resolve({
username: '',
password: 'PASS',
});
}));
});
targetUrl.search = 'password=PASS&realm=REALM';
await navigateControlledFrame(controlledframe, targetUrl.toString());
verifyWebRequestEvents([
'beforerequest',
'beforesendheaders',
'sendheaders',
'headersreceived',
'authrequired',
'responsestarted',
'completed',
]);
}, 'WebRequest Auth Async');
promise_test(async (test) => {
const controlledframe = await createControlledFrame('/simple.html', 'auth2');
controlledframe.stop();
const targetUrl = new URL(controlledframe.src);
targetUrl.pathname = '/auth-basic';
targetUrl.search = '*';
addWebRequestListeners(controlledframe, targetUrl.toString());
controlledframe.request.createWebRequestInterceptor({
urlPatterns: [targetUrl.toString()],
blocking: true,
}).addEventListener('authrequired', (e) => {
e.setCredentials({
username: '',
password: 'PASS',
});
});
targetUrl.search = 'password=PASS&realm=REALM';
await navigateControlledFrame(controlledframe, targetUrl.toString());
verifyWebRequestEvents([
'beforerequest',
'beforesendheaders',
'sendheaders',
'headersreceived',
'authrequired',
'responsestarted',
'completed',
]);
}, 'WebRequest Auth Sync');
promise_test(async (test) => {
const controlledframe = await createControlledFrame('/simple.html', 'noauth');
controlledframe.stop();
const targetUrl = new URL(controlledframe.src);
targetUrl.pathname = '/auth-basic';
targetUrl.search = '*';
addWebRequestListeners(controlledframe, targetUrl.toString());
controlledframe.request.createWebRequestInterceptor({
urlPatterns: [targetUrl.toString()],
blocking: true,
}).addEventListener('authrequired', (e) => {
e.setCredentials({
username: '',
password: 'WRONG_PASSWORD',
});
});
targetUrl.search = 'password=PASS&realm=REALM';
try {
await navigateControlledFrame(controlledframe, targetUrl.toString());
} catch (e) {}
assert_false(window.events.includes('completed'), 'completed fired');
assert_true(window.events.includes('authrequired'), 'authrequired fired');
assert_equals(
window.events.slice(-1)[0], 'erroroccurred', 'erroroccurred fired');
assert_equals(
window.occurredErrors[0], 'net::ERR_TOO_MANY_RETRIES', 'error code');
}, 'WebRequest Auth Fail');
promise_test(async (test) => {
const controlledframe = await createControlledFrame('/simple.html', 'noauth');
controlledframe.stop();
const targetUrl = new URL(controlledframe.src);
targetUrl.pathname = '/auth-basic';
targetUrl.search = '*';
addWebRequestListeners(controlledframe, targetUrl.toString());
const interceptor = controlledframe.request.createWebRequestInterceptor({
urlPatterns: [targetUrl.toString()],
blocking: true,
});
interceptor.addEventListener('authrequired', (e) => {
e.preventDefault();
});
let statusCode = -1;
interceptor.addEventListener('completed', (e) => {
statusCode = e.response.statusCode;
});
targetUrl.search = 'password=PASS&realm=REALM';
await navigateControlledFrame(controlledframe, targetUrl.toString());
verifyWebRequestEvents([
'beforerequest',
'beforesendheaders',
'sendheaders',
'headersreceived',
'authrequired',
'responsestarted',
'completed',
]);
assert_equals(statusCode, 401);
}, 'WebRequest Auth Cancel Sync');
promise_test(async (test) => {
const controlledframe = await createControlledFrame('/simple.html', 'noauth');
controlledframe.stop();
const targetUrl = new URL(controlledframe.src);
targetUrl.pathname = '/auth-basic';
targetUrl.search = '*';
addWebRequestListeners(controlledframe, targetUrl.toString());
const interceptor = controlledframe.request.createWebRequestInterceptor({
urlPatterns: [targetUrl.toString()],
blocking: true,
});
interceptor.addEventListener('authrequired', (e) => {
const controller = new AbortController();
e.setCredentials(new Promise(() => {}), {signal: controller.signal});
sleep(1).then(() => {
controller.abort();
});
});
let statusCode = -1;
interceptor.addEventListener('completed', (e) => {
statusCode = e.response.statusCode;
});
targetUrl.search = 'password=PASS&realm=REALM';
await navigateControlledFrame(controlledframe, targetUrl.toString());
verifyWebRequestEvents([
'beforerequest',
'beforesendheaders',
'sendheaders',
'headersreceived',
'authrequired',
'responsestarted',
'completed',
]);
assert_equals(statusCode, 401);
}, 'WebRequest Auth Cancel AbortSignal');
promise_test(async (test) => {
const controlledframe = await createControlledFrame('/simple.html', 'noauth');
controlledframe.stop();
const targetUrl = new URL(controlledframe.src);
targetUrl.pathname = '/auth-basic';
targetUrl.search = '*';
addWebRequestListeners(controlledframe, targetUrl.toString());
const interceptor = controlledframe.request.createWebRequestInterceptor({
urlPatterns: [targetUrl.toString()],
blocking: true,
});
interceptor.addEventListener('authrequired', (e) => {
const controller = new AbortController();
controller.abort();
e.setCredentials(new Promise(() => {}), {signal: controller.signal});
});
let statusCode = -1;
interceptor.addEventListener('completed', (e) => {
statusCode = e.response.statusCode;
});
targetUrl.search = 'password=PASS&realm=REALM';
await navigateControlledFrame(controlledframe, targetUrl.toString());
verifyWebRequestEvents([
'beforerequest',
'beforesendheaders',
'sendheaders',
'headersreceived',
'authrequired',
'responsestarted',
'completed',
]);
assert_equals(statusCode, 401);
}, 'WebRequest Auth Cancel Preaborted AbortSignal');
promise_test(async (test) => {
const controlledframe = await createControlledFrame('/simple.html', 'noauth');
controlledframe.stop();
const targetUrl = new URL(controlledframe.src);
targetUrl.pathname = '/auth-basic';
targetUrl.search = '*';
addWebRequestListeners(controlledframe, targetUrl.toString());
const interceptor = controlledframe.request.createWebRequestInterceptor({
urlPatterns: [targetUrl.toString()],
blocking: true,
});
interceptor.addEventListener('authrequired', (e) => {
// Ignore the event
});
let statusCode = -1;
interceptor.addEventListener('completed', (e) => {
statusCode = e.response.statusCode;
});
targetUrl.search = 'password=PASS&realm=REALM';
await navigateControlledFrame(
controlledframe, targetUrl.toString(), /*expectFailure=*/true);
verifyWebRequestEvents([
'beforerequest',
'beforesendheaders',
'sendheaders',
'headersreceived',
'authrequired',
'responsestarted',
'completed',
]);
assert_equals(statusCode, 401);
}, 'WebRequest Auth Noop');