{"id":23908931,"url":"https://github.com/germanaizek/webdriverxx","last_synced_at":"2025-04-06T18:13:37.770Z","repository":{"id":40485974,"uuid":"260953878","full_name":"GermanAizek/webdriverxx","owner":"GermanAizek","description":"Client API for Selenium Server","archived":false,"fork":false,"pushed_at":"2025-03-20T16:29:32.000Z","size":49470,"stargazers_count":77,"open_issues_count":17,"forks_count":21,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-30T17:08:22.578Z","etag":null,"topics":["automation-framework","automation-selenium","automation-testing","automation-ui","c","cmake","cpp","cpp11","freebsd","google-test","gtest","linux","selenium","selenium-server","selenium-tests","selenium-webdriver","windows"],"latest_commit_sha":null,"homepage":"https://GermanAizek.github.io/webdriverxx","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/GermanAizek.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-05-03T15:07:58.000Z","updated_at":"2025-03-23T19:14:50.000Z","dependencies_parsed_at":"2025-02-06T14:13:44.633Z","dependency_job_id":"34986c1d-b336-445d-94f0-b0f868e6b366","html_url":"https://github.com/GermanAizek/webdriverxx","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GermanAizek%2Fwebdriverxx","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GermanAizek%2Fwebdriverxx/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GermanAizek%2Fwebdriverxx/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GermanAizek%2Fwebdriverxx/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/GermanAizek","download_url":"https://codeload.github.com/GermanAizek/webdriverxx/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247526760,"owners_count":20953143,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["automation-framework","automation-selenium","automation-testing","automation-ui","c","cmake","cpp","cpp11","freebsd","google-test","gtest","linux","selenium","selenium-server","selenium-tests","selenium-webdriver","windows"],"created_at":"2025-01-05T05:14:31.368Z","updated_at":"2025-04-06T18:13:37.700Z","avatar_url":"https://github.com/GermanAizek.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n# Webdriver++\n\nA C++ client library for [Selenium Webdriver](http://www.seleniumhq.org/).\nYou can use this library in any C++ project.\n\n*Only 4.x and more Selenium Server.*\n\nCOPYRIGHTS\n\n * 2018 - Current Herman Semenov ([germanaizek@yandex.ru](mailto:germanaizek@yandex.ru))\n * 2014 - 2018 Sergey Kogan ([sekogan@gmail.com](mailto:sekogan@gmail.com))\n * 2017 Ilya Durdyev (IDurdyev)\n \nSPECIAL THANKS\n\n * 2019 xingyun86 ([peipengshuai@hotmail.com](mailto:peipengshuai@hotmail.com))\n * 2020 xloem ([0xloem@gmail.com](mailto:0xloem@gmail.com))\n * 2021 SrMilton ([miltonmanuelcramos@gmail.com](mailto:miltonmanuelcramos@gmail.com)), Mecanik ([Norbert.Boros@liveguard-software.com](mailto:Norbert.Boros@liveguard-software.com))\n * 2022 Mecanik ([Norbert.Boros@liveguard-software.com](mailto:Norbert.Boros@liveguard-software.com)), No-47 ([jacquessetsee34@gmail.com](mailto:jacquessetsee34@gmail.com))\n * 2024 Foxgoblin Xing ([foxgoblin@shockwest.com](mailto:foxgoblin@shockwest.com))\n * 2025 DanielAtCosmicDNA (Daniel Kaminski) ([daniel@cosmicdna.co.uk](mailto:daniel@cosmicdna.co.uk))\n## Cloning repository\n\n```bash\ngit clone --recurse-submodules https://github.com/GermanAizek/webdriverxx.git\ncd webdriverxx\n```\n\n## Compilation requirements\n\n### Debian\n```bash\nsudo apt-get install cmake g++ make curl\n```\n### Ubuntu and Ubuntu Touch\n```bash\nsudo apt-get install cmake g++ make curl libcurl4-openssl-dev\n```\n### Arch Linux\n```bash\nsudo pacman -Syu cmake g++ make curl\n```\n### Gentoo\n```bash\nsudo emerge -av dev-util/cmake sys-devel/gcc sys-devel/make net-misc/curl\n```\n\n## Compile on Linux, FreeBSD, OpenBSD\n```bash\nmkdir build \u0026\u0026 cd build \u0026\u0026 cmake ..\nsudo make\n```\n\n## Compile on Windows\n```bash\nmkdir build\ncd build\ncmake ..\n# For example, open a solution in Visual Studio\n```\n\n## Install GeckoDriver or ChromeDriver on Linux\n\n### GeckoDriver\n\nTo work with GeckoDriver, you need any browser built on the Gecko engine.\n\nFirefox (ESR, Nightly), IceCat, Waterfox, Pale Moon, SeaMonkey and etc.\n\nIn our examples, we will install official stable Firefox.\n\n#### Debian, Ubuntu, Ubuntu Touch\n```bash\nsudo apt-get install geckodriver\n```\n#### Arch Linux\n```bash\nsudo pacman -Syu geckodriver\n```\n#### Gentoo\n```bash\nUSE=\"geckodriver\" sudo emerge -av www-client/firefox\n```\n\n### ChromeDriver\n\nTo work with chromedriver, you need any browser built on the Chromium engine.\n\nChromium, Google Chrome, Opera, Vivaldi and etc.\n\nIn our examples, we will install official stable Google Chrome.\n\n#### Debian, Ubuntu, Ubuntu Touch\n```bash\nsudo apt-get install chromium-driver\n```\n#### Arch Linux\n```bash\nsudo yay -S --aur aur/chromedriver\n```\n#### Gentoo\n```bash\nsudo emerge -av www-client/chromedriver-bin\n```\n\n## A quick example\n\n### Dependencies\n\nThe first thing you need is full runtime environment Java.\n\nYou need to download and run selenium-server-standalone.\n\n#### Windows\n\nDownload latest OpenJDK and unpack: https://openjdk.java.net/\n\nOfficial Selenium server can be seen here: https://selenium-release.storage.googleapis.com/index.html\n\nSet the path enviroment variable to OpenJDK or move to the OpenJDK folder\n\n```bash\njava -jar /path_to/selenium-server-4.0.0-beta-4.jar standalone\n```\n\n#### Linux\n\nDownload latest OpenJDK from packet manager distributions Linux.\n\n##### Debian, Ubuntu, Ubuntu Touch\n```bash\nsudo apt-get install default-jre\n```\n##### Arch Linux\n```bash\nsudo pacman -Syu jre-openjdk jre-openjdk-headless\n```\n##### Gentoo\n```bash\nsudo emerge -av virtual/jre\n```\n\nOfficial Selenium server can be seen here: https://selenium-release.storage.googleapis.com/index.html\n\n```bash\nwget https://selenium-release.storage.googleapis.com/4.0-beta-4/selenium-server-4.0.0-beta-4.jar\n```\n\nor download from AUR [here](https://aur.archlinux.org/packages/selenium-server-standalone/):\n\n```bash\nsudo yay -S --aur aur/selenium-server-standalone\n```\n\nAfter now you can start.\n\n##### Any Linux distribution\n\n```bash\njava -jar selenium-server-4.0.0-beta-4.jar standalone\n```\n\nIf Selenium server standalone was downloaded from AUR (Arch Linux), then:\n\n```bash\njava -jar /usr/share/selenium-server/selenium-server-standalone.jar\n```\n\n### Run Google Test for testing html pages\n\nOn Windows:\n\n```bash\ncd src/vcprojects/\n# Open a solution 'webdriverxx.sln' in Visual Studio and compile it\n```\n\nMore info in MSDN: [Build and run a C++ app project](https://docs.microsoft.com/en-us/cpp/build/vscpp-step-2-build?view=msvc-160)\n\n### Examples\n\nBuild CMakeLists in 'examples' folder and run binary.\n\nOn Linux:\n\n```bash\ncd examples/example_start_browsers\nmkdir build \u0026\u0026 cd build\ncmake ..\nmake\n./example_start_browsers\n```\n\n## Features\n\n- **Very lightweight framework** (When compared with all implementations of api selenium)\n- Chainable commands\n- Value-like objects compatible with STL containers\n- Header-only\n- Lightweight dependencies:\n    - [libcurl](http://curl.haxx.se/libcurl/)\n    - [picojson](https://github.com/kazuho/picojson)\n- Can be used with any testing framework\n- Linux, FreeBSD, OpenBSD, Mac and Windows\n- Tested on GCC 9.x, Clang 10.x and MSVC Visual Studio 2019\n\n## More examples\n\nAll examples are in 'examples' folder.\n\n### Use proxy\n\n```cpp\nWebDriver ie = Start(InternetExplorer().SetProxy(\n\tSocksProxy(\"127.0.0.1:3128\")\n\t\t.SetUsername(\"user\")\n\t\t.SetPassword(\"12345\")\n\t\t.SetNoProxyFor(\"custom.host\")\n\t));\n```\n\n```cpp\nWebDriver ff = Start(Firefox().SetProxy(DirectConnection()));\n```\n\n### Navigate browser\n\n```cpp\ndriver\n\t.Navigate(\"http://facebook.com\")\n\t.Navigate(\"http://twitter.com\")\n\t.Back()\n\t.Forward()\n\t.Refresh();\n```\n\n### Find elements\n\n```cpp\n// Throws exception if no match is found in the document\nElement menu = driver.FindElement(ById(\"menu\"));\n\n// Returns empty vector if no such elements\n// The search is performed inside the menu element\nstd::vector\u003cElement\u003e items = menu.FindElements(ByClass(\"item\"));\n```\n\n### Send keyboard input\n\n```cpp\n// Sends text input or a shortcut to the element\ndriver.FindElement(ByTag(\"input\")).SendKeys(\"Hello, world!\");\n\n// Sends text input or a shortcut to the active window\ndriver.SendKeys(Shortcut() \u003c\u003c keys::Control \u003c\u003c \"t\");\n```\n\n### Emulate mobile devices (only Chrome)\n```cpp\nchrome::MobileEmulation me;\nme.SetdeviceName(chrome::device::Get(\"Galaxy Note 3\"));\nWebDriver ff = Start(Chrome().SetMobileEmulation(me));\n```\n\n### Execute Javascript\n\n```cpp\n// Simple script, no parameters\ndriver.Execute(\"console.log('Hi there!')\");\n\n// A script with one parameter\ndriver.Execute(\"document.title = arguments[0]\", JsArgs() \u003c\u003c \"Cowabunga!\");\n\n// A script with more than one parameter\ndriver.Execute(\"document.title = arguments[0] + '-' + arguments[1]\",\n\t\tJsArgs() \u003c\u003c \"Beep\" \u003c\u003c \"beep\");\n\n// Arrays or containers can also be used as parameters\nconst char* ss[] = { \"Yabba\", \"dabba\", \"doo\" };\ndriver.Execute(\"document.title = arguments[0].join(', ')\", JsArgs() \u003c\u003c ss);\n\n// Even an Element can be passed to a script\nauto element = driver.FindElement(ByTag(\"input\"));\ndriver.Execute(\"arguments[0].value = 'That was nuts!'\", JsArgs() \u003c\u003c element);\n```\n\n### Get something from Javascript\n\n```cpp\n// Scalar types\nauto title = driver.Eval\u003cstd::string\u003e(\"return document.title\")\nauto number = driver.Eval\u003cint\u003e(\"return 123\");\nauto another_number = driver.Eval\u003cdouble\u003e(\"return 123.5\");\nauto flag = driver.Eval\u003cbool\u003e(\"return true\");\n\n// Containers (all std::back_inserter compatible)\nstd::vector\u003cstd::string\u003e v = driver.Eval\u003cstd::vector\u003cstd::string\u003e\u003e(\n\t\t\"return [ 'abc', 'def' ]\"\n\t\t);\n\n// Elements!\nElement document_element = driver.Eval\u003cElement\u003e(\"return document.documentElement\");\n```\n\n### [Wait implicitly](http://selenium-python.readthedocs.org/en/latest/waits.html) for asynchronous operations\n\n```cpp\ndriver.SetImplicitTimeoutMs(5000);\n\n// Should poll the DOM for 5 seconds before throwing an exception.\nauto element = driver.FindElement(ByName(\"async_element\"));\n```\n\n### [Wait explicitly](http://selenium-python.readthedocs.org/en/latest/waits.html) for asynchronous operations\n\n```cpp\n#include \u003cwebdriverxx/wait.h\u003e\n\nauto find_element = [\u0026]{ return driver.FindElement(ById(\"async_element\")); };\nElement element = WaitForValue(find_element);\n```\n\n```cpp\n#include \u003cwebdriverxx/wait.h\u003e\n\nauto element_is_selected = [\u0026]{\n\treturn driver.FindElement(ById(\"asynchronously_loaded_element\")).IsSelected();\n\t};\nWaitUntil(element_is_selected);\n```\n\n### Use matchers from [Google Mock](https://code.google.com/p/googlemock/) for waiting\n\n```cpp\n#define WEBDRIVERXX_ENABLE_GMOCK_MATCHERS\n#include \u003cwebdriverxx/wait_match.h\u003e\n\ndriver.Navigate(\"http://initial_url.host.net\");\nauto url = [\u0026]{ return driver.GetUrl(); };\nusing namespace ::testing;\nauto final_url = WaitForMatch(url, HasSubstr(\"some_magic\"));\n```\n\n### Testing with real browsers\n\nPrerequisites:\n- [Selenium Server (4.x and more)](http://www.seleniumhq.org/download/)\n\n#### Linux\n```bash\njava -jar selenium-server.jar standalone \u0026\n./webdriverxx --browser=\u003cfirefox|chrome|...\u003e\n```\n\n#### Windows\n```bash\njava -jar selenium-server.jar standalone\nwebdriverxx.exe --browser=\u003cfirefox|chrome|...\u003e\n```\n\n## Advanced topics\n\n### Unicode\n\nThe library is designed to be encoding-agnostic. It doesn't make\nany assumptions about encodings. All strings are transferred\nas is, without modifications.\n\nThe WebDriver protocol is based on UTF-8, so all strings passed\nto the library/received from the library should be/are encoded\nusing UTF-8.\n\n### Thread safety\n\n- Webdriver++ objects are not thread safe. It is not safe to use\nneither any single object nor different objects obtained from a single WebDriver\nconcurrently without synchronization. On the other side, Webdriver++ objects\ndon't use global variables so it is OK to use different instances of WebDriver\nin different threads.\n\n- The CURL library should be explicitly initialized if several WebDrivers are used from\nmultiple threads. Call `curl_global_init(CURL_GLOBAL_ALL);` from `\u003ccurl/curl.h\u003e`\nonce per process before using this library.\n\n### Use common capabilities for all browsers\n\n```cpp\nCapabilities common;\ncommon.SetProxy(DirectConnection());\nauto ff = Start(Firefox(common));\nauto ie = Start(InternetExplorer(common));\nauto gc = Start(Chrome(common));\n```\n\n### Use required capabilities\n\n```cpp\nCapabilities required = /* ... */;\nauto ff = Start(Firefox(), required);\n```\n\n### Use custom URL for connecting to WebDriver\n\n```cpp\nconst char* url = \"http://localhost:4444/wd/hub/\";\n\nauto ff = Start(Firefox(), url);\n\n// or\nauto ff = Start(Firefox(), Capabilities() /* required */, url);\n```\n\n### Transfer objects between C++ and Javascript\n\n```cpp\nnamespace custom {\n\nstruct Object {\n\tstd::string string;\n\tint number;\n};\n\n// Conversion functions should be in the same namespace as the object\npicojson::value CustomToJson(const Object\u0026 value) {\n\treturn JsonObject()\n\t\t.Set(\"string\", value.string)\n\t\t.Set(\"number\", value.number);\n}\n\nvoid CustomFromJson(const picojson::value\u0026 value, Object\u0026 result) {\n\tassert(value.is\u003cpicojson::object\u003e());\n\tresult.string = FromJson\u003cstd::string\u003e(value.get(\"string\"));\n\tresult.number = FromJson\u003cint\u003e(value.get(\"number\"));\n}\n\n} // namespace custom\n\ncustom::Object o1 = { \"abc\", 123 };\ndriver.Execute(\"var o1 = arguments[0];\", JsArgs() \u003c\u003c o1);\ncustom::Object o1_copy = driver.Eval\u003ccustom::Object\u003e(\"return o1\");\ncustom::Object o2 = driver.Eval\u003ccustom::Object\u003e(\"return { string: 'abc', number: 123 }\");\n```\n\n--------------------\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgermanaizek%2Fwebdriverxx","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgermanaizek%2Fwebdriverxx","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgermanaizek%2Fwebdriverxx/lists"}