headless_chrome/
lib.rs

1//! A high-level API to control headless Chrome or Chromium over the DevTools Protocol. It is the
2//! Rust equivalent of [Puppeteer](https://github.com/GoogleChrome/puppeteer), a Node library
3//! maintained by the Chrome DevTools team.
4//!
5//! It is not 100% feature compatible with Puppeteer, but there's enough here to satisfy most
6//! browser testing / web crawling use cases, and there are several 'advanced' features such as:
7//!
8//! - [network request interception](https://docs.rs/headless_chrome/latest/headless_chrome/browser/tab/struct.Tab.html#method.enable_request_interception)
9//! - [JavaScript coverage monitoring](https://docs.rs/headless_chrome/latest/headless_chrome/browser/tab/struct.Tab.html#method.take_precise_js_coverage)
10//! - [taking screenshots of elements or the entire page](https://docs.rs/headless_chrome/latest/headless_chrome/browser/tab/struct.Tab.html#method.capture_screenshot)
11//! - [saving pages to PDF](https://docs.rs/headless_chrome/latest/headless_chrome/browser/tab/struct.Tab.html#method.print_to_pdf)
12//! - ['headful' browsing](https://docs.rs/headless_chrome/latest/headless_chrome/struct.LaunchOptionsBuilder.html#method.headless)
13//! - automatic downloading of 'known good' Chromium binaries for Linux / Mac / Windows
14//! - [extension pre-loading](https://docs.rs/headless_chrome/latest/headless_chrome/struct.LaunchOptionsBuilder.html#method.extensions)
15//!
16//! # Quick Start
17//!
18//! ```no_run
19//!use std::error::Error;
20//!use headless_chrome::Browser;
21//!use headless_chrome::protocol::cdp::Page;
22//!
23//!fn browse_wikipedia() -> Result<(), Box<dyn Error>> {
24//!    let browser = Browser::default()?;
25//!
26//!    let tab = browser.new_tab()?;
27//!
28//!    // Navigate to wikipedia
29//!    tab.navigate_to("https://www.wikipedia.org")?;
30//!
31//!    // Wait for network/javascript/dom to make the search-box available
32//!    // and click it.
33//!    tab.wait_for_element("input#searchInput")?.click()?;
34//!
35//!    // Type in a query and press `Enter`
36//!    tab.type_str("WebKit")?.press_key("Enter")?;
37//!
38//!    // We should end up on the WebKit-page once navigated
39//!    let elem = tab.wait_for_element("#firstHeading")?;
40//!    assert!(tab.get_url().ends_with("WebKit"));
41//!
42//!    /// Take a screenshot of the entire browser window
43//!    let jpeg_data = tab.capture_screenshot(
44//!        Page::CaptureScreenshotFormatOption::Jpeg,
45//!        None,
46//!        None,
47//!        true)?;
48//!    // Save the screenshot to disc
49//!    std::fs::write("screenshot.jpeg", jpeg_data)?;
50//!
51//!    /// Take a screenshot of just the WebKit-Infobox
52//!    let png_data = tab
53//!        .wait_for_element("#mw-content-text > div > table.infobox.vevent")?
54//!        .capture_screenshot(Page::CaptureScreenshotFormatOption::Png)?;
55//!    // Save the screenshot to disc
56//!    std::fs::write("screenshot.png", png_data)?;
57//!
58//!    // Run JavaScript in the page
59//!    let remote_object = elem.call_js_fn(r#"
60//!        function getIdTwice () {
61//!            // `this` is always the element that you called `call_js_fn` on
62//!            const id = this.id;
63//!            return id + id;
64//!        }
65//!    "#, vec![], false)?;
66//!    match remote_object.value {
67//!        Some(returned_string) => {
68//!            dbg!(&returned_string);
69//!            assert_eq!(returned_string, "firstHeadingfirstHeading".to_string());
70//!        }
71//!        _ => unreachable!()
72//!    };
73//!
74//!    Ok(())
75//!}
76//! ```
77
78#![deny(clippy::pedantic)]
79#![warn(renamed_and_removed_lints)]
80#![allow(
81clippy::module_name_repetitions,
82clippy::doc_markdown, // a number of false positives here
83clippy::default_trait_access, // fails on output of derive_builder
84clippy::needless_pass_by_value, // would stop us creating and passing in LaunchOptions to browser in one statement
85clippy::unreadable_literal, // not really applicable for timestamps
86clippy::too_many_lines,
87clippy::type_repetition_in_bounds,
88clippy::used_underscore_binding,
89clippy::must_use_candidate,
90clippy::derive_partial_eq_without_eq, // f64 doesn't impl Eq, for autogen protocol.rs
91clippy::missing_errors_doc,
92clippy::missing_panics_doc,
93clippy::struct_excessive_bools,  // for autogen protocol.rs
94clippy::wildcard_imports, // for autogen protocol.rs
95clippy::cast_possible_truncation, // for types.rs:189 & 190
96clippy::cast_sign_loss, // for tab/element/mod.rs:492 & 493
97clippy::cast_lossless, // for tab/element/mod.rs:492 & 493
98ambiguous_wide_pointer_comparisons, // for tab/mod.rs:1415
99clippy::derivable_impls, // for types.rs Default for PrintToPDF because autogen
100clippy::type_complexity, // for transport/web_socket_connection.rs:133
101clippy::manual_let_else, // for transport/web_socket_connection.rs:142
102clippy::should_implement_trait, // for browser/mod.rs:106
103)]
104
105pub use browser::{
106    tab::{element::Element, Tab},
107    Browser, LaunchOptions, LaunchOptionsBuilder,
108};
109
110#[cfg(feature = "fetch")]
111pub use browser::FetcherOptions;
112
113#[cfg(feature = "fetch")]
114pub use browser::Revision;
115
116pub mod browser;
117pub mod protocol;
118pub mod types;
119pub mod util;
120
121#[cfg(feature = "nightly")]
122#[doc = include_str!("../README.md")]
123#[allow(dead_code)]
124type _READMETEST = ();