playwright/imp/core/
driver.rs

1use crate::imp::prelude::*;
2use std::{env, fs, io};
3use zip::{result::ZipError, ZipArchive};
4
5#[derive(Debug, Clone, PartialEq)]
6pub struct Driver {
7    path: PathBuf,
8}
9
10impl Driver {
11    const ZIP: &'static [u8] = include_bytes!(concat!(env!("OUT_DIR"), env!("SEP"), "driver.zip"));
12    const PLATFORM: &'static str = include_str!(concat!(env!("OUT_DIR"), env!("SEP"), "platform"));
13
14    pub fn install() -> io::Result<Self> {
15        let this = Self::new(Self::default_dest());
16        if !this.path.is_dir() {
17            this.prepare()?;
18        }
19        Ok(this)
20    }
21
22    /// Without prepare
23    pub fn new<P: Into<PathBuf>>(path: P) -> Self {
24        Self { path: path.into() }
25    }
26    ///
27    pub fn prepare(&self) -> Result<(), ZipError> {
28        fs::create_dir_all(&self.path)?;
29        let mut a = ZipArchive::new(io::Cursor::new(Self::ZIP))?;
30        a.extract(&self.path)
31    }
32
33    pub fn default_dest() -> PathBuf {
34        let base: PathBuf = dirs::cache_dir().unwrap_or_else(env::temp_dir);
35        let dir: PathBuf = [
36            base.as_os_str(),
37            "ms-playwright".as_ref(),
38            "playwright-rust".as_ref(),
39            "driver".as_ref(),
40        ]
41        .iter()
42        .collect();
43        dir
44    }
45
46    pub fn platform(&self) -> Platform {
47        match Self::PLATFORM {
48            "linux" => Platform::Linux,
49            "mac" => Platform::Mac,
50            "win32" => Platform::Win32,
51            "win32_x64" => Platform::Win32x64,
52            _ => unreachable!(),
53        }
54    }
55
56    pub fn executable(&self) -> PathBuf {
57        // For Playwright 1.50+, we use node + package/cli.js
58        // The old playwright.sh/playwright.cmd are no longer included
59        match self.platform() {
60            Platform::Linux | Platform::Mac => self.path.join("node"),
61            Platform::Win32 | Platform::Win32x64 => self.path.join("node.exe"),
62        }
63    }
64
65    /// Returns the path to the CLI script for Playwright 1.50+
66    pub fn cli_script(&self) -> PathBuf {
67        self.path.join("package").join("cli.js")
68    }
69}
70
71#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
72pub enum Platform {
73    Linux,
74    Win32,
75    Win32x64,
76    Mac,
77}
78
79#[cfg(test)]
80mod tests {
81    use super::*;
82
83    #[test]
84    fn install() {
85        let _driver = Driver::install().unwrap();
86    }
87}