WebDriver: Generalize asynchronous event handling

Instead of having N functions all implement the same practice of looping
until an async event has arrived, this templatizes the bulk of the work.
This commit is contained in:
Timothy Flynn 2024-10-10 20:41:56 -04:00 committed by Andreas Kling
commit 922837f31b
Notes: github-actions[bot] 2024-10-11 07:10:18 +00:00

View file

@ -183,23 +183,15 @@ ErrorOr<void, Web::WebDriver::Error> Session::ensure_current_window_handle_is_va
return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::NoSuchWindow, "Window not found"sv);
}
Web::WebDriver::Response Session::execute_script(JsonValue payload, ScriptMode mode) const
template<typename Handler, typename Action>
static Web::WebDriver::Response perform_async_action(Handler& handler, Action&& action)
{
ScopeGuard guard { [&]() { web_content_connection().on_script_executed = nullptr; } };
Optional<Web::WebDriver::Response> response;
web_content_connection().on_script_executed = [&](auto result) {
response = move(result);
};
switch (mode) {
case ScriptMode::Sync:
TRY(web_content_connection().execute_script(move(payload)));
break;
case ScriptMode::Async:
TRY(web_content_connection().execute_async_script(move(payload)));
break;
}
ScopeGuard guard { [&]() { handler = nullptr; } };
handler = [&](auto result) { response = move(result); };
TRY(action());
Core::EventLoop::current().spin_until([&]() {
return response.has_value();
@ -208,40 +200,31 @@ Web::WebDriver::Response Session::execute_script(JsonValue payload, ScriptMode m
return response.release_value();
}
Web::WebDriver::Response Session::execute_script(JsonValue payload, ScriptMode mode) const
{
return perform_async_action(web_content_connection().on_script_executed, [&]() {
switch (mode) {
case ScriptMode::Sync:
return web_content_connection().execute_script(move(payload));
case ScriptMode::Async:
return web_content_connection().execute_async_script(move(payload));
}
VERIFY_NOT_REACHED();
});
}
Web::WebDriver::Response Session::element_click(String element_id) const
{
ScopeGuard guard { [&]() { web_content_connection().on_actions_performed = nullptr; } };
Optional<Web::WebDriver::Response> response;
web_content_connection().on_actions_performed = [&](auto result) {
response = move(result);
};
TRY(web_content_connection().element_click(move(element_id)));
Core::EventLoop::current().spin_until([&]() {
return response.has_value();
return perform_async_action(web_content_connection().on_actions_performed, [&]() {
return web_content_connection().element_click(move(element_id));
});
return response.release_value();
}
Web::WebDriver::Response Session::perform_actions(JsonValue payload) const
{
ScopeGuard guard { [&]() { web_content_connection().on_actions_performed = nullptr; } };
Optional<Web::WebDriver::Response> response;
web_content_connection().on_actions_performed = [&](auto result) {
response = move(result);
};
TRY(web_content_connection().perform_actions(move(payload)));
Core::EventLoop::current().spin_until([&]() {
return response.has_value();
return perform_async_action(web_content_connection().on_actions_performed, [&]() {
return web_content_connection().perform_actions(move(payload));
});
return response.release_value();
}
}