Skip to content

Commit 933872b

Browse files
cyfung1031CodFrm
andauthored
✅ 更新 example/tests/gm_xhr_test.js (#1091)
* 更新 example/tests/gm_xhr_test.js * Update gm_xhr_test.js --------- Co-authored-by: 王一之 <yz@ggnb.top>
1 parent b2b2d5c commit 933872b

File tree

1 file changed

+296
-3
lines changed

1 file changed

+296
-3
lines changed

example/tests/gm_xhr_test.js

Lines changed: 296 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
// ==UserScript==
2-
// @name GM_xmlhttpRequest Exhaustive Test Harness v2
2+
// @name GM_xmlhttpRequest Exhaustive Test Harness v3
33
// @namespace tm-gmxhr-test
4-
// @version 1.2.0
4+
// @version 1.2.1
55
// @description Comprehensive in-page tests for GM_xmlhttpRequest: normal, abnormal, and edge cases with clear pass/fail output.
66
// @author you
77
// @match *://*/*?GM_XHR_TEST_SC
88
// @grant GM_xmlhttpRequest
99
// @connect httpbun.com
10-
// @connect ipv4.download.thinkbroadband.com
1110
// @connect nonexistent-domain-abcxyz.test
11+
// @connect raw.githubusercontent.com
12+
// @connect translate.googleapis.com
1213
// @noframes
1314
// ==/UserScript==
1415

@@ -60,6 +61,30 @@ const enableTool = true;
6061
return el;
6162
}
6263

64+
// value type helper
65+
const typing = (x) => {
66+
let t = x === null ? "null" : typeof x;
67+
if (!x) t = `<${t}>`;
68+
if (t === "object") {
69+
try {
70+
return x[Symbol.toStringTag] || "object";
71+
} catch (e) {}
72+
}
73+
return t;
74+
};
75+
76+
const statusCode = (response) => {
77+
return (+response.readyState + +response.status / 1000).toFixed(3);
78+
};
79+
80+
const resPrint = (r) => {
81+
const a = statusCode(r);
82+
const b1 = "response" in r ? typing(r.response) : "missing";
83+
const b2 = "responseText" in r ? typing(r.responseText) : "missing";
84+
const b3 = "responseXML" in r ? typing(r.responseXML) : "missing";
85+
return `${a};r=${b1};t=${b2};x=${b3}`;
86+
};
87+
6388
// ---------- Test Panel ----------
6489
const panel = h(
6590
"div",
@@ -1259,6 +1284,274 @@ const enableTool = true;
12591284
assertDeepEq(readyStateList, fetch ? [2, 4] : [1, 2, 3, 4], "status 200");
12601285
},
12611286
},
1287+
{
1288+
name: "General Sequence",
1289+
async run(fetch) {
1290+
const resultList = [];
1291+
const url = `https://raw.githubusercontent.com/mdn/content/54fd6eaad3924076e0b546e7eff1f6f466f6139f/.editorconfig?d=${Date.now()}`;
1292+
await new Promise((resolve, reject) =>
1293+
GM_xmlhttpRequest({
1294+
method: "GET",
1295+
url,
1296+
fetch,
1297+
nocache: true,
1298+
onreadystatechange: function (response) {
1299+
resultList.push("onreadystatechange " + resPrint(response));
1300+
},
1301+
onload: function (response) {
1302+
resultList.push("onload " + resPrint(response));
1303+
},
1304+
onloadend: function (response) {
1305+
resultList.push("onloadend " + resPrint(response));
1306+
resolve();
1307+
},
1308+
onerror: () => reject(),
1309+
ontimeout: () => reject(),
1310+
})
1311+
);
1312+
if (!fetch) {
1313+
assertDeepEq(
1314+
resultList,
1315+
[
1316+
"onreadystatechange 1.000;r=missing;t=missing;x=missing",
1317+
"onreadystatechange 2.200;r=missing;t=missing;x=missing",
1318+
"onreadystatechange 3.200;r=missing;t=missing;x=missing",
1319+
"onreadystatechange 4.200;r=string;t=string;x=XMLDocument",
1320+
"onload 4.200;r=string;t=string;x=XMLDocument",
1321+
"onloadend 4.200;r=string;t=string;x=XMLDocument",
1322+
],
1323+
"standard-type GMXhr OK"
1324+
);
1325+
} else {
1326+
assertDeepEq(
1327+
resultList,
1328+
[
1329+
"onreadystatechange 2.200;r=missing;t=missing;x=missing",
1330+
"onreadystatechange 4.200;r=string;t=string;x=XMLDocument",
1331+
"onload 4.200;r=string;t=string;x=XMLDocument",
1332+
"onloadend 4.200;r=string;t=string;x=XMLDocument",
1333+
],
1334+
"fetch-type GMXhr OK"
1335+
);
1336+
}
1337+
},
1338+
},
1339+
{
1340+
name: "Progress & JSON Fallback",
1341+
async run(fetch) {
1342+
const resultSet = new Set();
1343+
let progressCount = 0;
1344+
const url = `https://raw.githubusercontent.com/dscape/spell/3f1d4dd2a6dfcad65578eadaf29cae1800a1be13/test/resources/big.txt?d=${Date.now()}`;
1345+
await new Promise((resolve, reject) =>
1346+
GM_xmlhttpRequest({
1347+
method: "GET",
1348+
url,
1349+
fetch,
1350+
nocache: true,
1351+
responseType: "json",
1352+
onreadystatechange: function (response) {
1353+
resultSet.add("onreadystatechange " + resPrint(response));
1354+
},
1355+
onprogress: function (response) {
1356+
resultSet.add("onprogress " + resPrint(response));
1357+
progressCount++;
1358+
},
1359+
onload: function (response) {
1360+
resultSet.add("onload " + resPrint(response));
1361+
},
1362+
onloadend: function (response) {
1363+
resultSet.add("onloadend " + resPrint(response));
1364+
resolve();
1365+
},
1366+
onerror: () => reject(),
1367+
ontimeout: () => reject(),
1368+
})
1369+
);
1370+
const resultList = [...resultSet];
1371+
if (!fetch) {
1372+
assertEq(progressCount >= 2, true, "progressCount ok");
1373+
assertDeepEq(
1374+
resultList,
1375+
[
1376+
"onreadystatechange 1.000;r=missing;t=missing;x=missing",
1377+
"onreadystatechange 2.200;r=missing;t=missing;x=missing",
1378+
"onreadystatechange 3.200;r=missing;t=missing;x=missing",
1379+
"onprogress 3.200;r=missing;t=missing;x=missing",
1380+
"onprogress 4.200;r=missing;t=missing;x=missing",
1381+
"onreadystatechange 4.200;r=<undefined>;t=string;x=XMLDocument",
1382+
"onload 4.200;r=<undefined>;t=string;x=XMLDocument",
1383+
"onloadend 4.200;r=<undefined>;t=string;x=XMLDocument",
1384+
],
1385+
"standard-type GMXhr OK"
1386+
);
1387+
} else {
1388+
assertEq(progressCount >= 2, true, "progressCount ok");
1389+
assertDeepEq(
1390+
resultList,
1391+
[
1392+
"onreadystatechange 2.200;r=missing;t=missing;x=missing",
1393+
"onprogress 3.200;r=missing;t=missing;x=missing",
1394+
"onreadystatechange 4.200;r=<undefined>;t=string;x=XMLDocument",
1395+
"onload 4.200;r=<undefined>;t=string;x=XMLDocument",
1396+
"onloadend 4.200;r=<undefined>;t=string;x=XMLDocument",
1397+
],
1398+
"fetch-type GMXhr OK"
1399+
);
1400+
}
1401+
},
1402+
},
1403+
{
1404+
name: "Progress & JSON Object",
1405+
async run(fetch) {
1406+
const resultSet = new Set();
1407+
let progressCount = 0;
1408+
const url = `https://raw.githubusercontent.com/json-iterator/test-data/0bce379832b475a6c21726ce37f971f8d849513b/large-file.json?d=${Date.now()}`;
1409+
await new Promise((resolve, reject) =>
1410+
GM_xmlhttpRequest({
1411+
method: "GET",
1412+
url,
1413+
fetch,
1414+
nocache: true,
1415+
responseType: "json",
1416+
onreadystatechange: function (response) {
1417+
resultSet.add("onreadystatechange " + resPrint(response));
1418+
},
1419+
onprogress: function (response) {
1420+
resultSet.add("onprogress " + resPrint(response));
1421+
progressCount++;
1422+
},
1423+
onload: function (response) {
1424+
resultSet.add("onload " + resPrint(response));
1425+
},
1426+
onloadend: function (response) {
1427+
resultSet.add("onloadend " + resPrint(response));
1428+
resolve();
1429+
},
1430+
onerror: () => reject(),
1431+
ontimeout: () => reject(),
1432+
})
1433+
);
1434+
const resultList = [...resultSet];
1435+
if (!fetch) {
1436+
assertEq(progressCount >= 2, true, "progressCount ok");
1437+
assertDeepEq(
1438+
resultList,
1439+
[
1440+
"onreadystatechange 1.000;r=missing;t=missing;x=missing",
1441+
"onreadystatechange 2.200;r=missing;t=missing;x=missing",
1442+
"onreadystatechange 3.200;r=missing;t=missing;x=missing",
1443+
"onprogress 3.200;r=missing;t=missing;x=missing",
1444+
"onprogress 4.200;r=missing;t=missing;x=missing",
1445+
"onreadystatechange 4.200;r=object;t=string;x=XMLDocument",
1446+
"onload 4.200;r=object;t=string;x=XMLDocument",
1447+
"onloadend 4.200;r=object;t=string;x=XMLDocument",
1448+
],
1449+
"standard-type GMXhr OK"
1450+
);
1451+
} else {
1452+
assertEq(progressCount >= 2, true, "progressCount ok");
1453+
assertDeepEq(
1454+
resultList,
1455+
[
1456+
"onreadystatechange 2.200;r=missing;t=missing;x=missing",
1457+
"onprogress 3.200;r=missing;t=missing;x=missing",
1458+
"onreadystatechange 4.200;r=object;t=string;x=XMLDocument",
1459+
"onload 4.200;r=object;t=string;x=XMLDocument",
1460+
"onloadend 4.200;r=object;t=string;x=XMLDocument",
1461+
],
1462+
"fetch-type GMXhr OK"
1463+
);
1464+
}
1465+
},
1466+
},
1467+
{
1468+
name: "response.getAllResponseHeaders() [without headers in request]",
1469+
async run(fetch) {
1470+
let resultHeaders = null;
1471+
const getHeaders = (e) => {
1472+
if (!e) return new Headers();
1473+
var n = e.split("\r\n").map(function (t) {
1474+
var e = t.split(":");
1475+
return [e[0].trim(), e[1].trim()];
1476+
});
1477+
return new Headers(n);
1478+
};
1479+
const url = `https://translate.googleapis.com/translate_a/single?client=gtx&sl=auto&tl=ja&dj=1&dt=t&dt=rm&q=%E3%81%8F%E3%82%8B%EF%BC%81%EF%BC%81%0A%E3%81%8F%E3%82%8B%E2%80%A6%0A%E3%81%8D%E3%81%9F%EF%BC%81%EF%BC%81%0Alets+go%0A%E3%81%8F%E3%82%8B%EF%BC%81%0Ayes%21`;
1480+
await new Promise((resolve, reject) =>
1481+
GM_xmlhttpRequest({
1482+
method: "GET",
1483+
url,
1484+
responseType: "blob",
1485+
headers: {},
1486+
fetch,
1487+
onload: function (response) {
1488+
resultHeaders = getHeaders(response.responseHeaders);
1489+
},
1490+
onloadend: function (response) {
1491+
resolve();
1492+
},
1493+
onerror: () => reject(),
1494+
ontimeout: () => reject(),
1495+
})
1496+
);
1497+
const headers = resultHeaders;
1498+
assertEq(headers.get("content-type"), "application/json; charset=utf-8", "content-type ok");
1499+
assertEq(
1500+
headers.get("reporting-endpoints").replace(/context=[-+\w]+/, "context=eJzj4tD"),
1501+
'default="/_/TranslateApiHttp/web-reports?context=eJzj4tD"',
1502+
"reporting-endpoints ok"
1503+
);
1504+
assertEq(headers.get("cross-origin-opener-policy"), "same-origin", "cross-origin-opener-policy ok");
1505+
assertEq(headers.get("content-encoding") !== "deflate", true, "content-encoding ok");
1506+
},
1507+
},
1508+
{
1509+
name: "response.getAllResponseHeaders() [with headers in request]",
1510+
async run(fetch) {
1511+
let resultHeaders = null;
1512+
const getHeaders = (e) => {
1513+
if (!e) return new Headers();
1514+
var n = e.split("\r\n").map(function (t) {
1515+
var e = t.split(":");
1516+
return [e[0].trim(), e[1].trim()];
1517+
});
1518+
return new Headers(n);
1519+
};
1520+
const url = `https://translate.googleapis.com/translate_a/single?client=gtx&sl=auto&tl=ja&dj=1&dt=t&dt=rm&q=%E3%81%8F%E3%82%8B%EF%BC%81%EF%BC%81%0A%E3%81%8F%E3%82%8B%E2%80%A6%0A%E3%81%8D%E3%81%9F%EF%BC%81%EF%BC%81%0Alets+go%0A%E3%81%8F%E3%82%8B%EF%BC%81%0Ayes%21`;
1521+
await new Promise((resolve, reject) =>
1522+
GM_xmlhttpRequest({
1523+
method: "GET",
1524+
url,
1525+
responseType: "blob",
1526+
headers: {
1527+
"Accept-Encoding": "deflate",
1528+
},
1529+
fetch,
1530+
onload: function (response) {
1531+
resultHeaders = getHeaders(response.responseHeaders);
1532+
},
1533+
onloadend: function (response) {
1534+
resolve();
1535+
},
1536+
onerror: () => reject(),
1537+
ontimeout: () => reject(),
1538+
})
1539+
);
1540+
const headers = resultHeaders;
1541+
assertEq(headers.get("content-type"), "application/json; charset=utf-8", "content-type ok");
1542+
assertEq(
1543+
headers.get("reporting-endpoints").replace(/context=[-+\w]+/, "context=eJzj4tD"),
1544+
'default="/_/TranslateApiHttp/web-reports?context=eJzj4tD"',
1545+
"reporting-endpoints ok"
1546+
);
1547+
assertEq(headers.get("cross-origin-opener-policy"), "same-origin", "cross-origin-opener-policy ok");
1548+
assertEq(
1549+
headers.get("content-encoding") === "deflate" || headers.get("content-encoding") === null,
1550+
true,
1551+
"content-encoding ok"
1552+
);
1553+
},
1554+
},
12621555
{
12631556
name: "Response headers line endings",
12641557
async run(fetch) {

0 commit comments

Comments
 (0)