1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210
// Copyright (C) 2023 Michael Lee
//
// This file is part of Wdc.
//
// Wdc is free software: you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the Free Software
// Foundation, either version 3 of the License, or (at your option) any later
// version.
//
// Wdc is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
// A PARTICULAR PURPOSE. See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along with
// Wdc. If not, see <https://www.gnu.org/licenses/>.
#![cfg_attr(doc_cfg, feature(doc_cfg))]
// #![feature(doc_auto_cfg)]
//!
//! A **W**eb**D**river **C**lient library.
//!
//! # Overview
//!
//! WebDriver is a widely-adopted W3C standard for web browser automation. It
//! defines algorithms in a platform-, language-independent manner. It
//! opens the possibility of using system programming languages such as Rust
//! or C/C++ for WebUI testing/browser automation, which leads to better
//! performance, efficiency, and safety.
//!
//! This crate provides a pure Rust implementation of
//! the client-side WebDriver, with the following goals:
//!
//! 1. **Standard Compliance**: it tracks both classical WebDriver and modern
//! BiDi standards.
//!
//! 2. **Low Overhead**: it has no runtime dependencies.
//!
//! 3. **Excellent Performance**: it strives for zero-copy operations.
//!
//! # Examples:
//! _Note: Assume using GeckoDriver, with default settings._
//!
//!
//! ## Navigate to website:
//!
//! ```
//! use wdc::{GeckoDriver, WdcError, WebDrvClient};
//!
//! go_w3c().unwrap();
//!
//! fn go_w3c() -> Result<(), WdcError> {
//! let wdc: WebDrvClient<GeckoDriver> = wdc::init("127.0.0.1", 4444, 10)?;
//! let url = "https://www.w3.org/standards";
//!
//! wdc.navi_to(url)?;
//! // ...whatever tests/automation on "w3.org"
//!
//! Ok(())
//! }
//! ```
//!
//! ## Run Javascript on website:
//!
//! ```
//! use wdc::{GeckoDriver, WdcError, WebDrvClient};
//!
//! check_out_w3c_history().unwrap();
//!
//! fn check_out_w3c_history() -> Result<(), WdcError> {
//! let wdc: WebDrvClient<GeckoDriver> = wdc::init("127.0.0.1", 4444, 10)?;
//! let url = "https://www.w3.org/Consortium/facts.html";
//!
//! let js_result = wdc.navi_to(url)?.exec_sync(
//! "return document.getElementById('history').nextElementSibling.innerText;",
//! vec![],
//! )?;
//!
//! let w3c_history = String::from_utf8_lossy(&js_result);
//! assert!(w3c_history.contains("Tim Berners-Lee"));
//! assert!(w3c_history.contains("World Wide Web"));
//! assert!(w3c_history.contains("HTML"));
//!
//! Ok(())
//! }
//! ```
#[cfg_attr(doc_cfg, doc(cfg(feature = "bidi")))]
#[allow(clippy::all)]
pub mod bidi;
#[allow(clippy::len_zero, clippy::manual_map, clippy::redundant_closure)]
pub mod wdcmd;
#[allow(clippy::len_zero, clippy::identity_op)]
mod httpp;
#[allow(clippy::len_zero, clippy::identity_op, clippy::needless_range_loop)]
mod wsp;
/// steal from dbg!
macro_rules! dbgg {
() => {
#[cfg(feature = "devel")]
dbg!();
};
($val:expr $(,)?) => {
#[cfg(feature = "devel")]
dbg!($val);
};
($($val:expr),+ $(,)?) => {
#[cfg(feature = "devel")]
($(dbg!($val)),+);
};
}
macro_rules! dbgmsg {
($fmtstr:expr) => {
#[cfg(feature = "devel")]
let dbgmsg = format!($fmtstr);
#[cfg(feature = "devel")]
dbg!(dbgmsg);
};
($fmtstr:expr, $($val:expr),+ $(,)?) => {
#[cfg(feature = "devel")]
let dbgmsg = format!($fmtstr, $($val),+);
#[cfg(feature = "devel")]
dbg!(dbgmsg);
};
}
macro_rules! run_diag {
($phase:expr, $blk:block) => {
#[cfg(feature = "diag")]
let start = std::time::Instant::now();
$blk;
#[cfg(feature = "diag")]
let dura = start.elapsed();
#[cfg(feature = "diag")]
let diag_msg = format!("{}: {:?}", $phase, dura);
#[cfg(feature = "diag")]
dbg!(diag_msg);
};
}
pub(crate) use dbgg;
pub(crate) use dbgmsg;
pub(crate) use run_diag;
// STRUCT //
// WdcError //
///
/// The WebDriver client-specific errors.
#[derive(PartialEq, Debug)]
pub enum WdcError {
///
/// A possible bug found.
Buggy,
BusyCreateSession,
DriverNotReadyBusySession,
NotReadyForNewSession,
///
/// The operation is not supported by corresponding WebDriver client.
UnsupportedOperation,
///
/// The WebDriver server is not ready for command processing.
WebDriverNotReady,
///
/// The connection to WebDriver server cannot be established.
WebDriverRemoteConnectionFailed,
///
/// The command cannot be processed successfully by WebDriver server.
///
/// The first field corresponds to the "error" field of standard WebDriver
/// error response, the second corresponds to the "message" field.
BadDrvCmd(String, String),
}
#[allow(clippy::len_zero)]
mod genericdrv;
#[cfg_attr(doc_cfg, doc(cfg(feature = "firefox")))]
#[cfg(feature = "firefox")]
mod geckodrv;
#[cfg(feature = "chromium")]
mod chromedrv;
// Generic //
pub use genericdrv::init;
pub use genericdrv::init_singl;
pub use genericdrv::CreateW3cSession;
pub use genericdrv::CreateWebDrvClient;
pub use genericdrv::WebDrvClient;
#[cfg_attr(doc_cfg, doc(cfg(feature = "firefox")))]
#[cfg(feature = "firefox")]
pub use geckodrv::init_singl_ff;
#[cfg_attr(doc_cfg, doc(cfg(feature = "firefox")))]
#[cfg(feature = "firefox")]
pub use geckodrv::GeckoDriver;
#[cfg_attr(doc_cfg, doc(cfg(feature = "chromium")))]
#[cfg(feature = "chromium")]
pub use chromedrv::init_singl_ch;
#[cfg_attr(doc_cfg, doc(cfg(feature = "chromium")))]
#[cfg(feature = "chromium")]
pub use chromedrv::ChromeDriver;