LibWeb: Add a test-only API to spoof the current URL and origin

This is not that easy to use for test developers, as forgetting to set
the url back to its original state after testing your specific API will
cause future navigations to fail in inexplicable ways.
This commit is contained in:
Andrew Kaster 2024-09-14 21:16:46 -06:00 committed by Tim Ledbetter
parent f0270b92f1
commit acd604c5e1
Notes: github-actions[bot] 2024-09-20 21:42:25 +00:00
5 changed files with 38 additions and 3 deletions

View file

@ -383,12 +383,14 @@ XMLHttpRequest
XMLHttpRequestEventTarget
XMLHttpRequestUpload
XMLSerializer
__finishTest
__preventMultipleTestFunctions
animationFrame
asyncTest
printElement
println
promiseTest
spoofCurrentURL
test
timeout
webkitURL

View file

@ -1,5 +1,6 @@
var __outputElement = null;
let __alreadyCalledTest = false;
let __originalURL = null;
function __preventMultipleTestFunctions() {
if (__alreadyCalledTest) {
throw new Error("You must only call test() or asyncTest() once per page");
@ -10,9 +11,24 @@ function __preventMultipleTestFunctions() {
if (globalThis.internals === undefined) {
internals = {
signalTextTestIsDone: function () {},
spoofCurrentURL: function (url) {},
};
}
function __finishTest() {
if (__originalURL) {
internals.spoofCurrentURL(__originalURL);
}
internals.signalTextTestIsDone();
}
function spoofCurrentURL(url) {
if (__originalURL === null) {
__originalURL = document.location.href;
}
internals.spoofCurrentURL(url);
}
function println(s) {
__outputElement.appendChild(document.createTextNode(s + "\n"));
}
@ -46,14 +62,14 @@ function test(f) {
__preventMultipleTestFunctions();
document.addEventListener("DOMContentLoaded", f);
window.addEventListener("load", () => {
internals.signalTextTestIsDone();
__finishTest();
});
}
function asyncTest(f) {
const done = () => {
__preventMultipleTestFunctions();
internals.signalTextTestIsDone();
__finishTest();
};
document.addEventListener("DOMContentLoaded", () => {
f(done);
@ -64,7 +80,7 @@ function promiseTest(f) {
document.addEventListener("DOMContentLoaded", () => {
f().then(() => {
__preventMultipleTestFunctions();
internals.signalTextTestIsDone();
__finishTest();
});
});
}

View file

@ -10,6 +10,7 @@
#include <LibWeb/DOM/Document.h>
#include <LibWeb/DOM/Event.h>
#include <LibWeb/DOM/EventTarget.h>
#include <LibWeb/DOMURL/DOMURL.h>
#include <LibWeb/HTML/BrowsingContext.h>
#include <LibWeb/HTML/HTMLElement.h>
#include <LibWeb/HTML/Window.h>
@ -136,6 +137,19 @@ WebIDL::ExceptionOr<bool> Internals::dispatch_user_activated_event(DOM::EventTar
return target.dispatch_event(event);
}
void Internals::spoof_current_url(String const& url_string)
{
auto url = DOMURL::parse(url_string);
VERIFY(url.is_valid());
auto origin = DOMURL::url_origin(url);
auto& window = internals_window();
window.associated_document().set_url(url);
window.associated_document().set_origin(origin);
}
JS::NonnullGCPtr<InternalAnimationTimeline> Internals::create_internal_animation_timeline()
{
auto& realm = this->realm();

View file

@ -35,6 +35,8 @@ public:
WebIDL::ExceptionOr<bool> dispatch_user_activated_event(DOM::EventTarget&, DOM::Event& event);
void spoof_current_url(String const& url);
JS::NonnullGCPtr<InternalAnimationTimeline> create_internal_animation_timeline();
void simulate_drag_start(double x, double y, String const& name, String const& contents);

View file

@ -19,6 +19,7 @@ interface Internals {
undefined wheel(double x, double y, double deltaX, double deltaY);
boolean dispatchUserActivatedEvent(EventTarget target, Event event);
undefined spoofCurrentURL(USVString url);
InternalAnimationTimeline createInternalAnimationTimeline();