Merge pull request #1038 from lightpanda-io/migrate_some_tests_10
Some checks failed
e2e-test / zig build release (push) Has been cancelled
e2e-test / demo-scripts (push) Has been cancelled
e2e-test / cdp-and-hyperfine-bench (push) Has been cancelled
e2e-test / perf-fmt (push) Has been cancelled
zig-test / zig build dev (push) Has been cancelled
zig-test / browser fetch (push) Has been cancelled
zig-test / zig test (push) Has been cancelled
zig-test / perf-fmt (push) Has been cancelled
nightly build / build-linux-x86_64 (push) Has been cancelled
nightly build / build-linux-aarch64 (push) Has been cancelled
nightly build / build-macos-aarch64 (push) Has been cancelled
nightly build / build-macos-x86_64 (push) Has been cancelled
wpt / web platform tests json output (push) Has been cancelled
wpt / perf-fmt (push) Has been cancelled

migrate more tests to htmlRunner
This commit is contained in:
Karl Seguin
2025-09-11 00:24:17 +08:00
committed by GitHub
10 changed files with 284 additions and 331 deletions

View File

@@ -166,74 +166,3 @@ pub const Console = struct {
fn timestamp() u32 {
return @import("../../datetime.zig").timestamp();
}
// const testing = @import("../../testing.zig");
// test "Browser.Console" {
// defer testing.reset();
// var runner = try testing.jsRunner(testing.tracking_allocator, .{});
// defer runner.deinit();
// {
// try runner.testCases(&.{
// .{ "console.log('a')", "undefined" },
// .{ "console.warn('hello world', 23, true, new Object())", "undefined" },
// }, .{});
// const captured = test_capture.captured.items;
// try testing.expectEqual("[info] args= 1: a", captured[0]);
// try testing.expectEqual("[warn] args= 1: hello world 2: 23 3: true 4: #<Object>", captured[1]);
// }
// {
// test_capture.reset();
// try runner.testCases(&.{
// .{ "console.countReset()", "undefined" },
// .{ "console.count()", "undefined" },
// .{ "console.count('teg')", "undefined" },
// .{ "console.count('teg')", "undefined" },
// .{ "console.count('teg')", "undefined" },
// .{ "console.count()", "undefined" },
// .{ "console.countReset('teg')", "undefined" },
// .{ "console.countReset()", "undefined" },
// .{ "console.count()", "undefined" },
// }, .{});
// const captured = test_capture.captured.items;
// try testing.expectEqual("[invalid counter] label=default", captured[0]);
// try testing.expectEqual("[count] label=default count=1", captured[1]);
// try testing.expectEqual("[count] label=teg count=1", captured[2]);
// try testing.expectEqual("[count] label=teg count=2", captured[3]);
// try testing.expectEqual("[count] label=teg count=3", captured[4]);
// try testing.expectEqual("[count] label=default count=2", captured[5]);
// try testing.expectEqual("[count reset] label=teg count=3", captured[6]);
// try testing.expectEqual("[count reset] label=default count=2", captured[7]);
// try testing.expectEqual("[count] label=default count=1", captured[8]);
// }
// {
// test_capture.reset();
// try runner.testCases(&.{
// .{ "console.assert(true)", "undefined" },
// .{ "console.assert('a', 2, 3, 4)", "undefined" },
// .{ "console.assert('')", "undefined" },
// .{ "console.assert('', 'x', true)", "undefined" },
// .{ "console.assert(false, 'x')", "undefined" },
// }, .{});
// const captured = test_capture.captured.items;
// try testing.expectEqual("[assertion failed] values=", captured[0]);
// try testing.expectEqual("[assertion failed] values= 1: x 2: true", captured[1]);
// try testing.expectEqual("[assertion failed] values= 1: x", captured[2]);
// }
// {
// test_capture.reset();
// try runner.testCases(&.{
// .{ "[1].forEach(console.log)", null },
// }, .{});
// const captured = test_capture.captured.items;
// try testing.expectEqual("[info] args= 1: 1 2: 0 3: [1]", captured[0]);
// }
// }

View File

@@ -29,12 +29,6 @@ pub fn constructor() File {
}
const testing = @import("../../testing.zig");
test "Browser.File" {
var runner = try testing.jsRunner(testing.tracking_allocator, .{ .html = "" });
defer runner.deinit();
try runner.testCases(&.{
.{ "let f = new File()", null },
.{ "f instanceof File", "true" },
}, .{});
test "Browser: File" {
try testing.htmlRunner("xhr/file.html");
}

View File

@@ -100,7 +100,7 @@ pub const FormData = struct {
return kv.urlEncode(self.entries, .form, writer);
}
log.warn(.web_api, "not implemented", .{
log.debug(.web_api, "not implemented", .{
.feature = "form data encoding",
.encoding = encoding,
});
@@ -265,132 +265,11 @@ fn getSubmitterName(submitter_: ?*parser.ElementHTML) !?[]const u8 {
}
const testing = @import("../../testing.zig");
test "Browser.FormData" {
var runner = try testing.jsRunner(testing.tracking_allocator, .{ .html =
\\ <form id="form1">
\\ <input id="has_no_name" value="nope1">
\\ <input id="is_disabled" disabled value="nope2">
\\
\\ <input name="txt-1" value="txt-1-v">
\\ <input name="txt-2" value="txt-~-v" type=password>
\\
\\ <input name="chk-3" value="chk-3-va" type=checkbox>
\\ <input name="chk-3" value="chk-3-vb" type=checkbox checked>
\\ <input name="chk-3" value="chk-3-vc" type=checkbox checked>
\\ <input name="chk-4" value="chk-4-va" type=checkbox>
\\ <input name="chk-4" value="chk-4-va" type=checkbox>
\\
\\ <input name="rdi-1" value="rdi-1-va" type=radio>
\\ <input name="rdi-1" value="rdi-1-vb" type=radio>
\\ <input name="rdi-1" value="rdi-1-vc" type=radio checked>
\\ <input name="rdi-2" value="rdi-2-va" type=radio>
\\ <input name="rdi-2" value="rdi-2-vb" type=radio>
\\
\\ <textarea name="ta-1"> ta-1-v</textarea>
\\ <textarea name="ta"></textarea>
\\
\\ <input type=hidden name=h1 value="h1-v">
\\ <input type=hidden name=h2 value="h2-v" disabled=disabled>
\\
\\ <select name="sel-1"><option>blue<option>red</select>
\\ <select name="sel-2"><option>blue<option value=sel-2-v selected>red</select>
\\ <select name="sel-3"><option disabled>nope1<option>nope2</select>
\\ <select name="mlt-1" multiple><option>water<option>tea</select>
\\ <select name="mlt-2" multiple><option selected>water<option selected>tea<option>coffee</select>
\\ <input type=submit id=s1 name=s1 value=s1-v>
\\ <input type=submit name=s2 value=s2-v>
\\ <input type=image name=i1 value=i1-v>
\\ </form>
\\ <input type=text name=abc value=123 form=form1>
});
defer runner.deinit();
try runner.testCases(&.{
.{ "let f = new FormData()", null },
.{ "f.get('a')", "null" },
.{ "f.has('a')", "false" },
.{ "f.getAll('a')", "" },
.{ "f.delete('a')", "undefined" },
.{ "f.set('a', 1)", "undefined" },
.{ "f.has('a')", "true" },
.{ "f.get('a')", "1" },
.{ "f.getAll('a')", "1" },
.{ "f.append('a', 2)", "undefined" },
.{ "f.has('a')", "true" },
.{ "f.get('a')", "1" },
.{ "f.getAll('a')", "1,2" },
.{ "f.append('b', '3')", "undefined" },
.{ "f.has('a')", "true" },
.{ "f.get('a')", "1" },
.{ "f.getAll('a')", "1,2" },
.{ "f.has('b')", "true" },
.{ "f.get('b')", "3" },
.{ "f.getAll('b')", "3" },
.{ "let acc = [];", null },
.{ "for (const key of f.keys()) { acc.push(key) }; acc;", "a,a,b" },
.{ "acc = [];", null },
.{ "for (const value of f.values()) { acc.push(value) }; acc;", "1,2,3" },
.{ "acc = [];", null },
.{ "for (const entry of f.entries()) { acc.push(entry) }; acc;", "a,1,a,2,b,3" },
.{ "acc = [];", null },
.{ "for (const entry of f) { acc.push(entry) }; acc;", "a,1,a,2,b,3" },
.{ "f.delete('a')", "undefined" },
.{ "f.has('a')", "false" },
.{ "f.has('b')", "true" },
.{ "acc = [];", null },
.{ "for (const key of f.keys()) { acc.push(key) }; acc;", "b" },
.{ "acc = [];", null },
.{ "for (const value of f.values()) { acc.push(value) }; acc;", "3" },
.{ "acc = [];", null },
.{ "for (const entry of f.entries()) { acc.push(entry) }; acc;", "b,3" },
.{ "acc = [];", null },
.{ "for (const entry of f) { acc.push(entry) }; acc;", "b,3" },
}, .{});
try runner.testCases(&.{
.{ "let form1 = document.getElementById('form1')", null },
.{ "let input = document.createElement('input');", null },
.{ "input.name = 'dyn'; input.value= 'dyn-v'; form1.appendChild(input);", null },
.{ "let submit1 = document.getElementById('s1')", null },
.{ "let f2 = new FormData(form1, submit1)", null },
.{ "acc = '';", null },
.{
\\ for (const entry of f2) {
\\ acc += entry[0] + '=' + entry[1] + '\n';
\\ };
\\ acc.slice(0, -1)
,
\\txt-1=txt-1-v
\\txt-2=txt-~-v
\\chk-3=chk-3-vb
\\chk-3=chk-3-vc
\\rdi-1=rdi-1-vc
\\ta-1= ta-1-v
\\ta=
\\h1=h1-v
\\sel-1=blue
\\sel-2=sel-2-v
\\mlt-2=water
\\mlt-2=tea
\\s1=s1-v
\\dyn=dyn-v
},
}, .{});
test "Browser: FormData" {
try testing.htmlRunner("xhr/form_data.html");
}
test "Browser.FormData: urlEncode" {
test "Browser: FormData.urlEncode" {
var arr: std.ArrayListUnmanaged(u8) = .empty;
defer arr.deinit(testing.allocator);

View File

@@ -67,18 +67,6 @@ pub const ProgressEvent = struct {
};
const testing = @import("../../testing.zig");
test "Browser.XHR.ProgressEvent" {
var runner = try testing.jsRunner(testing.tracking_allocator, .{});
defer runner.deinit();
try runner.testCases(&.{
.{ "let pevt = new ProgressEvent('foo');", "undefined" },
.{ "pevt.loaded", "0" },
.{ "pevt instanceof ProgressEvent", "true" },
.{ "var nnb = 0; var eevt = null; function ccbk(event) { nnb ++; eevt = event; }", "undefined" },
.{ "document.addEventListener('foo', ccbk)", "undefined" },
.{ "document.dispatchEvent(pevt)", "true" },
.{ "eevt.type", "foo" },
.{ "eevt instanceof ProgressEvent", "true" },
}, .{});
test "Browser: XHR.ProgressEvent" {
try testing.htmlRunner("xhr/progress_event.html");
}

View File

@@ -755,117 +755,6 @@ pub const XMLHttpRequest = struct {
};
const testing = @import("../../testing.zig");
test "Browser.XHR.XMLHttpRequest" {
var runner = try testing.jsRunner(testing.tracking_allocator, .{});
defer runner.deinit();
try runner.testCases(&.{
.{ "var nb = 0; var evt = null; function cbk(event) { nb ++; evt = event; }", "undefined" },
.{ "const req = new XMLHttpRequest()", "undefined" },
.{ "req.onload = cbk", "function cbk(event) { nb ++; evt = event; }" },
.{ "req.onload", "function cbk(event) { nb ++; evt = event; }" },
.{ "req.onload = cbk", "function cbk(event) { nb ++; evt = event; }" },
.{ "req.open('GET', 'http://127.0.0.1:9582/xhr')", null },
// ensure open resets values
.{ "req.status ", "0" },
.{ "req.statusText", "" },
.{ "req.getAllResponseHeaders()", "" },
.{ "req.getResponseHeader('Content-Type')", "null" },
.{ "req.responseText", "" },
.{ "req.send(); nb", "0" },
// Each case executed waits for all loop callback calls.
// So the url has been retrieved.
.{ "nb", "1" },
.{ "evt.type", "load" },
.{ "evt.loaded > 0", "true" },
.{ "evt instanceof ProgressEvent", "true" },
.{ "req.status", "200" },
.{ "req.statusText", "OK" },
.{ "req.getResponseHeader('Content-Type')", "text/html; charset=utf-8" },
.{ "req.getAllResponseHeaders()", "content-length: 100\r\n" ++
"Content-Type: text/html; charset=utf-8\r\n" },
.{ "req.responseText.length", "100" },
.{ "req.response.length == req.responseText.length", "true" },
.{ "req.responseXML instanceof Document", "true" },
}, .{});
try runner.testCases(&.{
.{ "const req2 = new XMLHttpRequest()", "undefined" },
.{ "req2.open('GET', 'http://127.0.0.1:9582/xhr')", "undefined" },
.{ "req2.responseType = 'document'", "document" },
.{ "req2.send()", "undefined" },
// Each case executed waits for all loop callaback calls.
// So the url has been retrieved.
.{ "req2.status", "200" },
.{ "req2.statusText", "OK" },
.{ "req2.response instanceof Document", "true" },
.{ "req2.responseXML instanceof Document", "true" },
}, .{});
try runner.testCases(&.{
.{ "const req3 = new XMLHttpRequest()", "undefined" },
.{ "req3.open('GET', 'http://127.0.0.1:9582/xhr/json')", "undefined" },
.{ "req3.responseType = 'json'", "json" },
.{ "req3.send()", "undefined" },
// Each case executed waits for all loop callaback calls.
// So the url has been retrieved.
.{ "req3.status", "200" },
.{ "req3.statusText", "OK" },
.{ "req3.response.over", "9000!!!" },
}, .{});
try runner.testCases(&.{
.{ "const req4 = new XMLHttpRequest()", "undefined" },
.{ "req4.open('POST', 'http://127.0.0.1:9582/xhr')", "undefined" },
.{ "req4.send('foo')", "undefined" },
// Each case executed waits for all loop callaback calls.
// So the url has been retrieved.
.{ "req4.status", "200" },
.{ "req4.statusText", "OK" },
.{ "req4.responseText.length > 64", "true" },
}, .{});
try runner.testCases(&.{
.{ "const req5 = new XMLHttpRequest()", "undefined" },
.{ "req5.open('GET', 'http://127.0.0.1:9582/xhr')", "undefined" },
.{ "var status = 0; req5.onload = function () { status = this.status };", "function () { status = this.status }" },
.{ "req5.send()", "undefined" },
// Each case executed waits for all loop callaback calls.
// So the url has been retrieved.
.{ "status", "200" },
}, .{});
try runner.testCases(&.{
.{ "const req6 = new XMLHttpRequest()", null },
.{
\\ var readyStates = [];
\\ var currentTarget = null;
\\ req6.onreadystatechange = (e) => {
\\ currentTarget = e.currentTarget;
\\ readyStates.push(req6.readyState);
\\ }
,
null,
},
.{ "req6.open('GET', 'http://127.0.0.1:9582/xhr')", null },
.{ "req6.send()", null },
.{ "readyStates.length", "4" },
.{ "readyStates[0] === XMLHttpRequest.OPENED", "true" },
.{ "readyStates[1] === XMLHttpRequest.HEADERS_RECEIVED", "true" },
.{ "readyStates[2] === XMLHttpRequest.LOADING", "true" },
.{ "readyStates[3] === XMLHttpRequest.DONE", "true" },
.{ "currentTarget == req6", "true" },
}, .{});
test "Browser: XHR.XMLHttpRequest" {
try testing.htmlRunner("xhr/xhr.html");
}

View File

@@ -92,6 +92,15 @@
_registerErrorCallback();
}
async function async(promise, cb) {
const script_id = document.currentScript.id;
const stack = new Error().stack;
const value = await promise;
this._captured = {script_id: script_id, stack: stack};
cb(value);
this._captured = null;
}
function _recordExecution() {
if (testing._status === 'fail') {
return;
@@ -161,6 +170,7 @@
_executed_scripts: new Set(),
_captured: null,
skip: skip,
async: async,
getStatus: getStatus,
eventually: eventually,
expectEqual: expectEqual,
@@ -177,4 +187,9 @@
window.$$ = function(sel) {
return document.querySelectorAll(sel);
}
if (!console.lp) {
// make this work in the browser
console.lp = console.log;
}
})();

5
src/tests/xhr/file.html Normal file
View File

@@ -0,0 +1,5 @@
<script src="../testing.js"></script>
<script id=file>
let f = new File()
testing.expectEqual(true, f instanceof File);
</script>

View File

@@ -0,0 +1,129 @@
<script src="../testing.js"></script>
<script id=formData>
let f = new FormData();
testing.expectEqual(null, f.get('a'));
testing.expectEqual(false, f.has('a'));
testing.expectEqual([], f.getAll('a'));
testing.expectEqual(undefined, f.delete('a'));
f.set('a', 1);
testing.expectEqual(true, f.has('a'));
testing.expectEqual('1', f.get('a'));
testing.expectEqual(['1'], f.getAll('a'));
f.append('a', 2);
testing.expectEqual(true, f.has('a'));
testing.expectEqual('1', f.get('a'));
testing.expectEqual(['1', '2'], f.getAll('a'));
f.append('b', '3');
testing.expectEqual(true, f.has('a'));
testing.expectEqual('1', f.get('a'));
testing.expectEqual(['1', '2'], f.getAll('a'));
testing.expectEqual(true, f.has('b'));
testing.expectEqual('3', f.get('b'));
testing.expectEqual(['3'], f.getAll('b'));
let acc = [];
for (const key of f.keys()) { acc.push(key) }
testing.expectEqual(['a', 'a', 'b'], acc);
acc = [];
for (const value of f.values()) { acc.push(value) }
testing.expectEqual(['1', '2', '3'], acc);
acc = [];
for (const entry of f.entries()) { acc.push(entry) }
testing.expectEqual([['a', '1'], ['a', '2'], ['b', '3']], acc);
acc = [];
for (const entry of f) { acc.push(entry) };
testing.expectEqual([['a', '1'], ['a', '2'], ['b', '3']], acc);
f.delete('a');
testing.expectEqual(false, f.has('a'));
testing.expectEqual(true, f.has('b'));
acc = [];
for (const key of f.keys()) { acc.push(key) }
testing.expectEqual(['b'], acc);
acc = [];
for (const value of f.values()) { acc.push(value) }
testing.expectEqual(['3'], acc);
acc = [];
for (const entry of f.entries()) { acc.push(entry) }
testing.expectEqual([['b', '3']], acc);
acc = [];
for (const entry of f) { acc.push(entry) }
testing.expectEqual([['b', '3']], acc);
</script>
<script id=serialize>
let form1 = $('#form1');
let submit1 = $('#s1');
let input = document.createElement('input');
input.name = 'dyn';
input.value = 'dyn-v';
form1.appendChild(input);
let f2 = new FormData(form1, submit1);
acc = [];
for (const entry of f2) {
acc.push(entry);
};
testing.expectEqual(['txt-1', 'txt-1-v'], acc[0]);
testing.expectEqual(['txt-2', 'txt-~-v'], acc[1]);
testing.expectEqual(['chk-3', 'chk-3-vb'], acc[2]);
testing.expectEqual(['chk-3', 'chk-3-vc'], acc[3]);
testing.expectEqual(['rdi-1', 'rdi-1-vc'], acc[4]);
testing.expectEqual(['ta-1', ' ta-1-v'], acc[5]);
testing.expectEqual(['ta', ''], acc[6]);
testing.expectEqual(['h1', 'h1-v'], acc[7]);
testing.expectEqual(['sel-1', 'blue'], acc[8]);
testing.expectEqual(['sel-2', 'sel-2-v'], acc[9]);
testing.expectEqual(['mlt-2', 'water'], acc[10]);
testing.expectEqual(['mlt-2', 'tea'], acc[11]);
testing.expectEqual(['s1', 's1-v'], acc[12]);
testing.expectEqual(['dyn', 'dyn-v'], acc[13]);
</script>
<form id="form1">
<input id="has_no_name" value="nope1">
<input id="is_disabled" disabled value="nope2">
<input name="txt-1" value="txt-1-v">
<input name="txt-2" value="txt-~-v" type=password>
<input name="chk-3" value="chk-3-va" type=checkbox>
<input name="chk-3" value="chk-3-vb" type=checkbox checked>
<input name="chk-3" value="chk-3-vc" type=checkbox checked>
<input name="chk-4" value="chk-4-va" type=checkbox>
<input name="chk-4" value="chk-4-va" type=checkbox>
<input name="rdi-1" value="rdi-1-va" type=radio>
<input name="rdi-1" value="rdi-1-vb" type=radio>
<input name="rdi-1" value="rdi-1-vc" type=radio checked>
<input name="rdi-2" value="rdi-2-va" type=radio>
<input name="rdi-2" value="rdi-2-vb" type=radio>
<textarea name="ta-1"> ta-1-v</textarea>
<textarea name="ta"></textarea>
<input type=hidden name=h1 value="h1-v">
<input type=hidden name=h2 value="h2-v" disabled=disabled>
<select name="sel-1"><option>blue<option>red</select>
<select name="sel-2"><option>blue<option value=sel-2-v selected>red</select>
<select name="sel-3"><option disabled>nope1<option>nope2</select>
<select name="mlt-1" multiple><option>water<option>tea</select>
<select name="mlt-2" multiple><option selected>water<option selected>tea<option>coffee</select>
<input type=submit id=s1 name=s1 value=s1-v>
<input type=submit name=s2 value=s2-v>
<input type=image name=i1 value=i1-v>
</form>
<input type=text name=abc value=123 form=form1>

View File

@@ -0,0 +1,16 @@
<script src="../testing.js"></script>
<script id=progressEvent>
let pevt = new ProgressEvent('foo');
testing.expectEqual(0, pevt.loaded);
testing.expectEqual(true, pevt instanceof ProgressEvent);
var eevt = null;
function ccbk(event) {
eevt = event;
}
document.addEventListener('foo', ccbk)
document.dispatchEvent(pevt);
testing.expectEqual('foo', eevt.type);
testing.expectEqual(true, eevt instanceof ProgressEvent);
</script>

109
src/tests/xhr/xhr.html Normal file
View File

@@ -0,0 +1,109 @@
<script src="../testing.js"></script>
<script id=xhr type=module>
const req = new XMLHttpRequest();
const promise1 = new Promise((resolve) => {
function cbk(event) {
resolve(event)
}
req.onload = cbk;
testing.expectEqual(cbk, req.onload);
req.onload = cbk;
req.open('GET', 'http://127.0.0.1:9582/xhr');
testing.expectEqual(0, req.status);
testing.expectEqual('', req.statusText);
testing.expectEqual('', req.getAllResponseHeaders());
testing.expectEqual(null, req.getResponseHeader('Content-Type'));
testing.expectEqual('', req.responseText);
req.send();
});
testing.async(promise1, (event) => {
testing.expectEqual('load', event.type);
testing.expectEqual(true, event.loaded > 0);
testing.expectEqual(true, event instanceof ProgressEvent);
testing.expectEqual(200, req.status);
testing.expectEqual('OK', req.statusText);
testing.expectEqual('text/html; charset=utf-8', req.getResponseHeader('Content-Type'));
testing.expectEqual('content-length: 100\r\nContent-Type: text/html; charset=utf-8\r\n', req.getAllResponseHeaders());
testing.expectEqual(100, req.responseText.length);
testing.expectEqual(req.responseText.length, req.response.length);
testing.expectEqual(true, req.responseXML instanceof Document);
});
</script>
<script id=xhr2 type=module>
const req2 = new XMLHttpRequest()
const promise2 = new Promise((resolve) => {
req2.onload = resolve;
req2.open('GET', 'http://127.0.0.1:9582/xhr')
req2.responseType = 'document';
req2.send()
});
testing.async(promise2, () => {
testing.expectEqual(200, req2.status);
testing.expectEqual('OK', req2.statusText);
testing.expectEqual(true, req2.response instanceof Document);
testing.expectEqual(true, req2.responseXML instanceof Document);
});
</script>
<script id=xhr3 type=module>
const req3 = new XMLHttpRequest()
const promise3 = new Promise((resolve) => {
req3.onload = resolve;
req3.open('GET', 'http://127.0.0.1:9582/xhr/json')
req3.responseType = 'json';
req3.send()
});
testing.async(promise3, () => {
testing.expectEqual(200, req3.status);
testing.expectEqual('OK', req3.statusText);
testing.expectEqual('9000!!!', req3.response.over);
});
</script>
<script id=xhr4 type=module>
const req4 = new XMLHttpRequest()
const promise4 = new Promise((resolve) => {
req4.onload = resolve;
req4.open('POST', 'http://127.0.0.1:9582/xhr')
req4.send('foo')
});
testing.async(promise4, () => {
testing.expectEqual(200, req4.status);
testing.expectEqual('OK', req4.statusText);
testing.expectEqual(true, req4.responseText.length > 64);
});
</script>
<script id=xhr5 type=module>
const promise5 = new Promise((resolve) => {
var state = [];
const req5 = new XMLHttpRequest();
req5.onreadystatechange = (e) => {
state.push(req5.readyState);
if (req5.readyState === XMLHttpRequest.DONE) {
resolve({states: state, target: e.currentTarget});
}
}
req5.open('GET', 'http://127.0.0.1:9582/xhr');
req5.send();
});
testing.async(promise5, (result) => {
const {states: states, target: target} = result;
testing.expectEqual(4, states.length)
testing.expectEqual(XMLHttpRequest.OPENED, readyStates[0]);
testing.expectEqual(XMLHttpRequest.HEADERS_RECEIVED, readyStates[1]);
testing.expectEqual(XMLHttpRequest.LOADING, readyStates[2]);
testing.expectEqual(XMLHttpRequest.DONE, readyStates[3]);
testing.expectEqual(req5, target);
})
</script>