Skip to content

Instantly share code, notes, and snippets.

@dotproto
Last active July 17, 2024 23:36
Show Gist options
  • Save dotproto/43cba54752300484b69ca0d0ecc1c82c to your computer and use it in GitHub Desktop.
Save dotproto/43cba54752300484b69ca0d0ecc1c82c to your computer and use it in GitHub Desktop.
`onAuthRequired` event handler test cases

This gist contains a browser extension that tests browser support for testing how onAuthRequired event handlers handle different resoultion patterns. It created in support of reviewing https://github.com/mdn/webextensions-examples/pull/564.

Test # extraInfoSpec Description Chrome Firefox
1 blocking Synchronous object response
2 blocking Synchronous Promise response with async resolution
3 asyncBlocking Synchronous object response
4 asyncBlocking Synchronous Promise response with async resolution
5 asyncBlocking Async callback call with object
globalThis.browser ??= chrome;
let target = "https://httpbin.org/basic-auth/*";
let pendingRequests = [];
/*
A request has completed. We can stop worrying about it.
*/
function completed(requestDetails) {
console.log("completed: " + requestDetails.requestId);
let index = pendingRequests.indexOf(requestDetails.requestId);
if (index > -1) {
pendingRequests.splice(index, 1);
}
}
const ASYNC_DELAY = 1_000;
const credentialProvider = {
// Test 1 - "blocking" request with synchronous response
test1() {
console.log(`Test 1 - "blocking" request with synchronous response`)
return {
authCredentials: {
username: "test1",
password: "pass"
}
};
},
// Test 2 - "blocking" request with Promise response
test2() {
console.log(`Test 2 - "blocking" request with Promise response`)
return new Promise(resolve => {
setTimeout(() => {
console.log(`Test 2 - timer expired, resolving promise with response`);
resolve({
authCredentials: {
username: "test2",
password: "pass"
}
});
}, ASYNC_DELAY);
});
},
// Test 3 - "asyncBlocking" request with synchronous response
test3() {
console.log(`Test 3 - "asyncBlocking" request with synchronous response`)
return {
authCredentials: {
username: "test3",
password: "pass"
}
};
},
// Test 4 - "asyncBlocking" request with Promise response
test4() {
console.log(`Test 4 - "asyncBlocking" request with Promise response`)
return new Promise(resolve => {
setTimeout(() => {
console.log(`Test 4 - timer expired, resolving promise with response`);
resolve({
authCredentials: {
username: "test4",
password: "pass"
}
});
}, ASYNC_DELAY);
});
},
// Test 5 - "asyncBlocking" request with callback response
test5(_details, callback) {
console.log(`Test 5 - "asyncBlocking" request with callback response`)
setTimeout(() => {
console.log(`Test 5 - timer expired, calling callback with response`);
callback({
authCredentials: {
username: "test5",
password: "pass"
}
});
}, ASYNC_DELAY);
},
}
function provideCredentialsAsync(details, callback) {
// If we have seen this request before,
// then assume our credentials were bad,
// and give up.
if (pendingRequests.indexOf(details.requestId) != -1) {
console.log("bad credentials for: " + details.requestId);
return {cancel: true};
} else {
pendingRequests.push(details.requestId);
console.log("providing credentials for: " + details.requestId);
const url = new URL(details.url);
const pathParts = url.pathname.substring(1).split('/');
const username = pathParts[1];
const response = credentialProvider[username](details, callback);
if (response) {
return response;
}
}
}
browser.webRequest.onAuthRequired.addListener(
provideCredentialsAsync,
{urls: [
"https://httpbin.org/basic-auth/test1/*",
"https://httpbin.org/basic-auth/test2/*",
]},
["blocking"]
);
browser.webRequest.onAuthRequired.addListener(
// Wrap the call in order to a collision with re-registering the same function
(...args) => provideCredentialsAsync(...args),
{urls: [
"https://httpbin.org/basic-auth/test3/*",
"https://httpbin.org/basic-auth/test4/*",
"https://httpbin.org/basic-auth/test5/*",
]},
["asyncBlocking"]
);
browser.webRequest.onCompleted.addListener(
completed,
{urls: [target]}
);
browser.webRequest.onErrorOccurred.addListener(
completed,
{urls: [target]}
);
browser.runtime.onInstalled.addListener(() => {
browser.windows.create({
url: [
"https://httpbin.org/basic-auth/test1/pass",
"https://httpbin.org/basic-auth/test2/pass",
"https://httpbin.org/basic-auth/test3/pass",
"https://httpbin.org/basic-auth/test4/pass",
"https://httpbin.org/basic-auth/test5/pass",
]
});
});
{
"name": "onAuthRequired test cases",
"version": "3.0",
"manifest_version": 3,
"background": {
"scripts": ["background.js"],
"service_worker": "background.js"
},
"permissions": [
"webRequest",
"webRequestBlocking",
"webRequestAuthProvider"
],
"host_permissions": [
"https://httpbin.org/basic-auth/*"
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment