Skip to content

Commit

Permalink
[WebDriver][WPE][GTK] Enable WebDriver connection to already running …
Browse files Browse the repository at this point in the history
…browser

https://bugs.webkit.org/show_bug.cgi?id=270630

Reviewed by Carlos Garcia Campos.

In some embedded cases WebDriver needs to be able to connect to already
existing instance of browser running automation session. There's already
code in WebDriver to support this scenario but it's not used in WPE/GTK.

* Source/WebDriver/Capabilities.h:
* Source/WebDriver/SessionHost.h:
* Source/WebDriver/WebDriverService.cpp:
(WebDriver::printUsageStatement):
(WebDriver::WebDriverService::run):
(WebDriver::WebDriverService::connectToBrowser):
* Source/WebDriver/WebDriverService.h:
* Source/WebDriver/glib/SessionHostGlib.cpp:
(WebDriver::SessionHost::isConnected const):
(WebDriver::SessionHost::launchBrowser):
(WebDriver::SessionHost::connectToBrowser):
(WebDriver::SessionHost::connectionDidClose):
* Source/WebDriver/gtk/WebDriverServiceGtk.cpp:
(WebDriver::WebDriverService::platformParseCapabilities const):
* Source/WebDriver/wpe/WebDriverServiceWPE.cpp:
(WebDriver::WebDriverService::platformParseCapabilities const):

Canonical link: https://commits.webkit.org/276231@main
  • Loading branch information
zhani authored and carlosgcampos committed Mar 16, 2024
1 parent 244f327 commit 56dbddd
Show file tree
Hide file tree
Showing 7 changed files with 52 additions and 26 deletions.
6 changes: 2 additions & 4 deletions Source/WebDriver/Capabilities.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ struct Capabilities {
std::optional<PageLoadStrategy> pageLoadStrategy;
std::optional<UnhandledPromptBehavior> unhandledPromptBehavior;
std::optional<Proxy> proxy;
std::optional<String> targetAddr;
std::optional<int> targetPort;
#if PLATFORM(GTK) || PLATFORM(WPE)
std::optional<String> browserBinary;
std::optional<Vector<String>> browserArguments;
Expand All @@ -83,10 +85,6 @@ struct Capabilities {
#if PLATFORM(GTK)
std::optional<bool> useOverlayScrollbars;
#endif
#if USE(INSPECTOR_SOCKET_SERVER)
std::optional<String> targetAddr;
std::optional<int> targetPort;
#endif
};

} // namespace WebDriver
8 changes: 4 additions & 4 deletions Source/WebDriver/SessionHost.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,7 @@ class SessionHost
}
~SessionHost();

#if USE(INSPECTOR_SOCKET_SERVER)
void setHostAddress(const String& ip, uint16_t port) { m_targetIp = ip; m_targetPort = port; }
#endif
bool isConnected() const;

const String& sessionID() const { return m_sessionID; }
Expand Down Expand Up @@ -116,14 +114,16 @@ class SessionHost

HashMap<long, Function<void (CommandResponse&&)>> m_commandRequests;

String m_targetIp;
uint16_t m_targetPort { 0 };

#if USE(GLIB)
Function<void (bool, std::optional<String>)> m_startSessionCompletionHandler;
GRefPtr<GSubprocess> m_browser;
RefPtr<SocketConnection> m_socketConnection;
GRefPtr<GCancellable> m_cancellable;
bool m_isRemoteBrowser { false };
#elif USE(INSPECTOR_SOCKET_SERVER)
String m_targetIp;
uint16_t m_targetPort { 0 };
Function<void(bool, std::optional<String>)> m_startSessionCompletionHandler;
std::optional<Inspector::ConnectionID> m_clientID;
#endif
Expand Down
12 changes: 1 addition & 11 deletions Source/WebDriver/WebDriverService.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,20 +50,16 @@ static void printUsageStatement(const char* programName)
printf(" -h, --help Prints this help message\n");
printf(" -p <port>, --port=<port> Port number the driver will use\n");
printf(" --host=<host> Host IP the driver will use, or either 'local' or 'all' (default: 'local')\n");
#if USE(INSPECTOR_SOCKET_SERVER)
printf(" -t <ip:port> --target=<ip:port> [WinCairo] Target IP and port\n");
#endif
printf(" -t <ip:port> --target=<ip:port> Target IP and port\n");
}

int WebDriverService::run(int argc, char** argv)
{
String portString;
std::optional<String> host;
#if USE(INSPECTOR_SOCKET_SERVER)
String targetString;
if (const char* targetEnvVar = getenv("WEBDRIVER_TARGET_ADDR"))
targetString = String::fromLatin1(targetEnvVar);
#endif
for (int i = 1 ; i < argc; ++i) {
const char* arg = argv[i];
if (!strcmp(arg, "-h") || !strcmp(arg, "--help")) {
Expand Down Expand Up @@ -92,7 +88,6 @@ int WebDriverService::run(int argc, char** argv)
continue;
}

#if USE(INSPECTOR_SOCKET_SERVER)
if (!strcmp(arg, "-t") && targetString.isNull()) {
if (++i == argc) {
printUsageStatement(argv[0]);
Expand All @@ -107,23 +102,20 @@ int WebDriverService::run(int argc, char** argv)
targetString = String::fromLatin1(arg + targetStrLength);
continue;
}
#endif
}

if (portString.isNull()) {
printUsageStatement(argv[0]);
return EXIT_FAILURE;
}

#if USE(INSPECTOR_SOCKET_SERVER)
if (!targetString.isEmpty()) {
auto position = targetString.reverseFind(':');
if (position != notFound) {
m_targetAddress = targetString.left(position);
m_targetPort = parseIntegerAllowingTrailingJunk<uint16_t>(StringView { targetString }.substring(position + 1)).value_or(0);
}
}
#endif

auto port = parseInteger<uint16_t>(portString);
if (!port) {
Expand Down Expand Up @@ -834,9 +826,7 @@ void WebDriverService::connectToBrowser(Vector<Capabilities>&& capabilitiesList,

auto sessionHost = makeUnique<SessionHost>(capabilitiesList.takeLast());
auto* sessionHostPtr = sessionHost.get();
#if USE(INSPECTOR_SOCKET_SERVER)
sessionHostPtr->setHostAddress(m_targetAddress, m_targetPort);
#endif
sessionHostPtr->connectToBrowser([this, capabilitiesList = WTFMove(capabilitiesList), sessionHost = WTFMove(sessionHost), completionHandler = WTFMove(completionHandler)](std::optional<String> error) mutable {
if (error) {
completionHandler(CommandResult::fail(CommandResult::ErrorCode::SessionNotCreated, makeString("Failed to connect to browser: ", error.value())));
Expand Down
2 changes: 0 additions & 2 deletions Source/WebDriver/WebDriverService.h
Original file line number Diff line number Diff line change
Expand Up @@ -143,10 +143,8 @@ class WebDriverService final : public HTTPRequestHandler {
HTTPServer m_server;
RefPtr<Session> m_session;

#if USE(INSPECTOR_SOCKET_SERVER)
String m_targetAddress;
uint16_t m_targetPort { 0 };
#endif
};

} // namespace WebDriver
30 changes: 25 additions & 5 deletions Source/WebDriver/glib/SessionHostGlib.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ void SessionHost::connectToBrowser(Function<void (std::optional<String> error)>&
bool SessionHost::isConnected() const
{
// Session is connected when launching or when socket connection hasn't been closed.
return m_browser && (!m_socketConnection || !m_socketConnection->isClosed());
return (m_browser || m_isRemoteBrowser) && (!m_socketConnection || !m_socketConnection->isClosed());
}

struct ConnectToBrowserAsyncData {
Expand Down Expand Up @@ -134,10 +134,28 @@ static guint16 freePort()

void SessionHost::launchBrowser(Function<void (std::optional<String> error)>&& completionHandler)
{
String targetIp;
uint16_t targetPort = 0;

if (!m_targetIp.isEmpty() && m_targetPort) {
targetIp = m_targetIp;
targetPort = m_targetPort;
} else if (m_capabilities.targetAddr && m_capabilities.targetPort) {
targetIp = m_capabilities.targetAddr.value();
targetPort = m_capabilities.targetPort.value();
}

m_cancellable = adoptGRef(g_cancellable_new());
GUniquePtr<char> inspectorAddress(
g_strdup_printf("%s:%u", targetIp.isEmpty() ? "127.0.0.1" : targetIp.latin1().data(), targetPort > 0 ? targetPort : freePort())
);
if (!targetIp.isEmpty()) {
m_isRemoteBrowser = true;
connectToBrowser(makeUnique<ConnectToBrowserAsyncData>(this, WTFMove(inspectorAddress), m_cancellable.get(), WTFMove(completionHandler)));
return;
}

GRefPtr<GSubprocessLauncher> launcher = adoptGRef(g_subprocess_launcher_new(G_SUBPROCESS_FLAGS_NONE));
guint16 port = freePort();
GUniquePtr<char> inspectorAddress(g_strdup_printf("127.0.0.1:%u", port));
g_subprocess_launcher_setenv(launcher.get(), "WEBKIT_INSPECTOR_SERVER", inspectorAddress.get(), TRUE);
#if PLATFORM(GTK)
g_subprocess_launcher_setenv(launcher.get(), "GTK_OVERLAY_SCROLLING", m_capabilities.useOverlayScrollbars.value() ? "1" : "0", TRUE);
Expand Down Expand Up @@ -170,7 +188,7 @@ void SessionHost::launchBrowser(Function<void (std::optional<String> error)>&& c

void SessionHost::connectToBrowser(std::unique_ptr<ConnectToBrowserAsyncData>&& data)
{
if (!m_browser)
if (!m_browser && !m_isRemoteBrowser)
return;

RunLoop::main().dispatchAfter(100_ms, [connectToBrowserData = WTFMove(data)]() mutable {
Expand All @@ -192,10 +210,10 @@ void SessionHost::connectToBrowser(std::unique_ptr<ConnectToBrowserAsyncData>&&
data->sessionHost->connectToBrowser(WTFMove(data));
return;
}

data->completionHandler(String::fromUTF8(error->message));
return;
}

data->sessionHost->setupConnection(SocketConnection::create(WTFMove(connection), messageHandlers(), data->sessionHost));
data->completionHandler(std::nullopt);
}, data);
Expand All @@ -205,6 +223,8 @@ void SessionHost::connectToBrowser(std::unique_ptr<ConnectToBrowserAsyncData>&&
void SessionHost::connectionDidClose()
{
m_browser = nullptr;
m_isRemoteBrowser = false;

inspectorDisconnected();
m_socketConnection = nullptr;
}
Expand Down
10 changes: 10 additions & 0 deletions Source/WebDriver/gtk/WebDriverServiceGtk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include "Capabilities.h"
#include "CommandResult.h"
#include <wtf/JSONValues.h>
#include <wtf/text/StringToIntegerConversion.h>

namespace WebDriver {

Expand Down Expand Up @@ -159,6 +160,15 @@ void WebDriverService::platformParseCapabilities(const JSON::Object& matchedCapa
capabilities.certificates->append({ WTFMove(host), WTFMove(certificateFile) });
}
}

String targetString;
if (browserOptions->getString("targetAddress"_s, targetString)) {
auto position = targetString.reverseFind(':');
if (position != notFound) {
capabilities.targetAddr = targetString.left(position);
capabilities.targetPort = parseIntegerAllowingTrailingJunk<uint16_t>(StringView { targetString }.substring(position + 1)).value_or(0);
}
}
}

} // namespace WebDriver
10 changes: 10 additions & 0 deletions Source/WebDriver/wpe/WebDriverServiceWPE.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include "Capabilities.h"
#include "CommandResult.h"
#include <wtf/JSONValues.h>
#include <wtf/text/StringToIntegerConversion.h>

namespace WebDriver {

Expand Down Expand Up @@ -148,6 +149,15 @@ void WebDriverService::platformParseCapabilities(const JSON::Object& matchedCapa
capabilities.certificates->append({ WTFMove(host), WTFMove(certificateFile) });
}
}

String targetString;
if (browserOptions->getString("targetAddress"_s, targetString)) {
auto position = targetString.reverseFind(':');
if (position != notFound) {
capabilities.targetAddr = targetString.left(position);
capabilities.targetPort = parseIntegerAllowingTrailingJunk<uint16_t>(StringView { targetString }.substring(position + 1)).value_or(0);
}
}
}

} // namespace WebDriver

0 comments on commit 56dbddd

Please sign in to comment.