1/*
2 * Copyright (C) 2017 Igalia S.L.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 * THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#pragma once
27
28#include "HTTPServer.h"
29#include "Session.h"
30#include <wtf/Forward.h>
31#include <wtf/HashMap.h>
32#include <wtf/JSONValues.h>
33#include <wtf/text/StringHash.h>
34
35namespace WebDriver {
36
37struct Capabilities;
38class CommandResult;
39class Session;
40
41class WebDriverService final : public HTTPRequestHandler {
42public:
43 WebDriverService();
44 ~WebDriverService() = default;
45
46 int run(int argc, char** argv);
47
48 static bool platformCompareBrowserVersions(const String&, const String&);
49
50private:
51 enum class HTTPMethod { Get, Post, Delete };
52 typedef void (WebDriverService::*CommandHandler)(RefPtr<JSON::Object>&&, Function<void (CommandResult&&)>&&);
53 struct Command {
54 HTTPMethod method;
55 const char* uriTemplate;
56 CommandHandler handler;
57 };
58 static const Command s_commands[];
59
60 static Optional<HTTPMethod> toCommandHTTPMethod(const String& method);
61 static bool findCommand(HTTPMethod, const String& path, CommandHandler*, HashMap<String, String>& parameters);
62
63 void newSession(RefPtr<JSON::Object>&&, Function<void (CommandResult&&)>&&);
64 void deleteSession(RefPtr<JSON::Object>&&, Function<void (CommandResult&&)>&&);
65 void status(RefPtr<JSON::Object>&&, Function<void (CommandResult&&)>&&);
66 void getTimeouts(RefPtr<JSON::Object>&&, Function<void (CommandResult&&)>&&);
67 void setTimeouts(RefPtr<JSON::Object>&&, Function<void (CommandResult&&)>&&);
68 void go(RefPtr<JSON::Object>&&, Function<void (CommandResult&&)>&&);
69 void getCurrentURL(RefPtr<JSON::Object>&&, Function<void (CommandResult&&)>&&);
70 void back(RefPtr<JSON::Object>&&, Function<void (CommandResult&&)>&&);
71 void forward(RefPtr<JSON::Object>&&, Function<void (CommandResult&&)>&&);
72 void refresh(RefPtr<JSON::Object>&&, Function<void (CommandResult&&)>&&);
73 void getTitle(RefPtr<JSON::Object>&&, Function<void (CommandResult&&)>&&);
74 void getWindowHandle(RefPtr<JSON::Object>&&, Function<void (CommandResult&&)>&&);
75 void closeWindow(RefPtr<JSON::Object>&&, Function<void (CommandResult&&)>&&);
76 void switchToWindow(RefPtr<JSON::Object>&&, Function<void (CommandResult&&)>&&);
77 void getWindowHandles(RefPtr<JSON::Object>&&, Function<void (CommandResult&&)>&&);
78 void switchToFrame(RefPtr<JSON::Object>&&, Function<void (CommandResult&&)>&&);
79 void switchToParentFrame(RefPtr<JSON::Object>&&, Function<void (CommandResult&&)>&&);
80 void getWindowRect(RefPtr<JSON::Object>&&, Function<void (CommandResult&&)>&&);
81 void setWindowRect(RefPtr<JSON::Object>&&, Function<void (CommandResult&&)>&&);
82 void maximizeWindow(RefPtr<JSON::Object>&&, Function<void (CommandResult&&)>&&);
83 void minimizeWindow(RefPtr<JSON::Object>&&, Function<void (CommandResult&&)>&&);
84 void fullscreenWindow(RefPtr<JSON::Object>&&, Function<void (CommandResult&&)>&&);
85 void findElement(RefPtr<JSON::Object>&&, Function<void (CommandResult&&)>&&);
86 void findElements(RefPtr<JSON::Object>&&, Function<void (CommandResult&&)>&&);
87 void findElementFromElement(RefPtr<JSON::Object>&&, Function<void (CommandResult&&)>&&);
88 void findElementsFromElement(RefPtr<JSON::Object>&&, Function<void (CommandResult&&)>&&);
89 void getActiveElement(RefPtr<JSON::Object>&&, Function<void (CommandResult&&)>&&);
90 void isElementSelected(RefPtr<JSON::Object>&&, Function<void (CommandResult&&)>&&);
91 void getElementAttribute(RefPtr<JSON::Object>&&, Function<void (CommandResult&&)>&&);
92 void getElementProperty(RefPtr<JSON::Object>&&, Function<void (CommandResult&&)>&&);
93 void getElementCSSValue(RefPtr<JSON::Object>&&, Function<void (CommandResult&&)>&&);
94 void getElementText(RefPtr<JSON::Object>&&, Function<void (CommandResult&&)>&&);
95 void getElementTagName(RefPtr<JSON::Object>&&, Function<void (CommandResult&&)>&&);
96 void getElementRect(RefPtr<JSON::Object>&&, Function<void (CommandResult&&)>&&);
97 void isElementEnabled(RefPtr<JSON::Object>&&, Function<void (CommandResult&&)>&&);
98 void isElementDisplayed(RefPtr<JSON::Object>&&, Function<void (CommandResult&&)>&&);
99 void elementClick(RefPtr<JSON::Object>&&, Function<void (CommandResult&&)>&&);
100 void elementClear(RefPtr<JSON::Object>&&, Function<void (CommandResult&&)>&&);
101 void elementSendKeys(RefPtr<JSON::Object>&&, Function<void (CommandResult&&)>&&);
102 void executeScript(RefPtr<JSON::Object>&&, Function<void (CommandResult&&)>&&);
103 void executeAsyncScript(RefPtr<JSON::Object>&&, Function<void (CommandResult&&)>&&);
104 void getAllCookies(RefPtr<JSON::Object>&&, Function<void (CommandResult&&)>&&);
105 void getNamedCookie(RefPtr<JSON::Object>&&, Function<void (CommandResult&&)>&&);
106 void addCookie(RefPtr<JSON::Object>&&, Function<void (CommandResult&&)>&&);
107 void deleteCookie(RefPtr<JSON::Object>&&, Function<void (CommandResult&&)>&&);
108 void deleteAllCookies(RefPtr<JSON::Object>&&, Function<void (CommandResult&&)>&&);
109 void performActions(RefPtr<JSON::Object>&&, Function<void (CommandResult&&)>&&);
110 void releaseActions(RefPtr<JSON::Object>&&, Function<void (CommandResult&&)>&&);
111 void dismissAlert(RefPtr<JSON::Object>&&, Function<void (CommandResult&&)>&&);
112 void acceptAlert(RefPtr<JSON::Object>&&, Function<void (CommandResult&&)>&&);
113 void getAlertText(RefPtr<JSON::Object>&&, Function<void (CommandResult&&)>&&);
114 void sendAlertText(RefPtr<JSON::Object>&&, Function<void (CommandResult&&)>&&);
115 void takeScreenshot(RefPtr<JSON::Object>&&, Function<void (CommandResult&&)>&&);
116 void takeElementScreenshot(RefPtr<JSON::Object>&&, Function<void (CommandResult&&)>&&);
117
118 static Capabilities platformCapabilities();
119 Vector<Capabilities> processCapabilities(const JSON::Object&, Function<void (CommandResult&&)>&) const;
120 RefPtr<JSON::Object> validatedCapabilities(const JSON::Object&) const;
121 RefPtr<JSON::Object> mergeCapabilities(const JSON::Object&, const JSON::Object&) const;
122 RefPtr<JSON::Object> matchCapabilities(const JSON::Object&) const;
123 bool platformValidateCapability(const String&, const RefPtr<JSON::Value>&) const;
124 bool platformMatchCapability(const String&, const RefPtr<JSON::Value>&) const;
125 void parseCapabilities(const JSON::Object& desiredCapabilities, Capabilities&) const;
126 void platformParseCapabilities(const JSON::Object& desiredCapabilities, Capabilities&) const;
127 void connectToBrowser(Vector<Capabilities>&&, Function<void (CommandResult&&)>&&);
128 void createSession(Vector<Capabilities>&&, std::unique_ptr<SessionHost>&&, Function<void (CommandResult&&)>&&);
129 bool findSessionOrCompleteWithError(JSON::Object&, Function<void (CommandResult&&)>&);
130
131 void handleRequest(HTTPRequestHandler::Request&&, Function<void (HTTPRequestHandler::Response&&)>&& replyHandler) override;
132 void sendResponse(Function<void (HTTPRequestHandler::Response&&)>&& replyHandler, CommandResult&&) const;
133
134 HTTPServer m_server;
135 RefPtr<Session> m_session;
136};
137
138} // namespace WebDriver
139