mirror of https://github.com/dnaka91/obws
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
241 lines
6.8 KiB
Rust
241 lines
6.8 KiB
Rust
use std::{env, sync::Once};
|
|
|
|
use anyhow::{ensure, Result};
|
|
use obws::{
|
|
responses::{filters::SourceFilter, inputs::Input, scenes::Scene},
|
|
Client,
|
|
};
|
|
|
|
pub const TEST_PROFILE: &str = "OBWS-TEST";
|
|
pub const TEST_SCENE: &str = "OBWS-TEST-Scene";
|
|
pub const TEST_SCENE_2: &str = "OBWS-TEST-Scene2";
|
|
pub const TEST_SCENE_RENAME: &str = "OBWS-TEST-Scene-Renamed";
|
|
pub const TEST_SCENE_CREATE: &str = "OBWS-TEST-Scene-Created";
|
|
pub const TEST_TEXT: &str = "OBWS-TEST-Text";
|
|
pub const TEST_TEXT_2: &str = "OBWS-TEST-Text2";
|
|
pub const TEST_BROWSER: &str = "OBWS-TEST-Browser";
|
|
pub const TEST_BROWSER_RENAME: &str = "OBWS-TEST-Browser-Renamed";
|
|
pub const TEST_MEDIA: &str = "OBWS-TEST-Media";
|
|
pub const TEST_GROUP: &str = "OBWS-TEST-Group";
|
|
pub const TEST_TRANSITION: &str = "OBWS-TEST-Transition";
|
|
pub const TEST_FILTER: &str = "OBWS-TEST-Filter";
|
|
pub const TEST_FILTER_2: &str = "OBWS-TEST-Filter2";
|
|
pub const TEST_FILTER_RENAME: &str = "OBWS-TEST-Filter-Renamed";
|
|
pub const INPUT_KIND_TEXT_FT2: &str = "text_ft2_source_v2";
|
|
pub const INPUT_KIND_BROWSER: &str = "browser_source";
|
|
pub const INPUT_KIND_VLC: &str = "vlc_source";
|
|
pub const FILTER_COLOR: &str = "color_filter";
|
|
|
|
static INIT: Once = Once::new();
|
|
|
|
pub async fn new_client() -> Result<Client> {
|
|
INIT.call_once(|| {
|
|
dotenvy::dotenv().ok();
|
|
tracing_subscriber::fmt::init();
|
|
});
|
|
|
|
let host = env::var("OBS_HOST").unwrap_or_else(|_| "localhost".to_owned());
|
|
let port = env::var("OBS_PORT")
|
|
.map(|p| p.parse())
|
|
.unwrap_or(Ok(4455))?;
|
|
let client = Client::connect(host, port, env::var("OBS_PASSWORD").ok()).await?;
|
|
|
|
ensure_obs_setup(&client).await?;
|
|
|
|
Ok(client)
|
|
}
|
|
|
|
async fn ensure_obs_setup(client: &Client) -> Result<()> {
|
|
let scenes = client.scenes().list().await?;
|
|
ensure!(
|
|
scenes.scenes.iter().any(is_required_scene),
|
|
"scene `{}` not found, required for scenes tests",
|
|
TEST_SCENE
|
|
);
|
|
ensure!(
|
|
scenes.scenes.iter().any(is_required_scene_2),
|
|
"scene `{}` not found, required for scenes tests",
|
|
TEST_SCENE
|
|
);
|
|
ensure!(
|
|
!scenes.scenes.iter().any(is_renamed_scene),
|
|
"scene `{}` found, must NOT be present for scenes tests",
|
|
TEST_SCENE_RENAME
|
|
);
|
|
ensure!(
|
|
!scenes.scenes.iter().any(is_created_scene),
|
|
"scene `{}` found, must NOT be present for scenes tests",
|
|
TEST_SCENE_CREATE
|
|
);
|
|
|
|
let groups = client.scenes().list_groups().await?;
|
|
ensure!(
|
|
groups.iter().map(String::as_str).any(is_required_group),
|
|
"group `{}` not found, required for scenes and scene items tests",
|
|
TEST_GROUP
|
|
);
|
|
|
|
let inputs = client.inputs().list(None).await?;
|
|
ensure!(
|
|
inputs.iter().any(is_required_text_input),
|
|
"text input `{}` not found, required for inputs tests",
|
|
TEST_TEXT
|
|
);
|
|
ensure!(
|
|
inputs.iter().any(is_required_text_2_input),
|
|
"text input `{}` not found, required for inputs tests",
|
|
TEST_TEXT
|
|
);
|
|
ensure!(
|
|
inputs.iter().any(is_required_browser_input),
|
|
"media input `{}` not found, required for inputs tests",
|
|
TEST_BROWSER
|
|
);
|
|
ensure!(
|
|
inputs.iter().any(is_required_media_input),
|
|
"media input `{}` not found, required for inputs tests",
|
|
TEST_MEDIA
|
|
);
|
|
ensure!(
|
|
!inputs.iter().any(is_renamed_input),
|
|
"browser input `{}` found, must NOT be present for inputs tests",
|
|
TEST_BROWSER_RENAME
|
|
);
|
|
|
|
let filters = client.filters().list(TEST_TEXT).await?;
|
|
ensure!(
|
|
filters.iter().any(is_required_filter),
|
|
"filter `{}` not found, required for filters tests",
|
|
TEST_FILTER
|
|
);
|
|
ensure!(
|
|
!filters.iter().any(is_filter_2),
|
|
"filter `{}` found, must NOT be present for filters tests",
|
|
TEST_FILTER_2
|
|
);
|
|
ensure!(
|
|
!filters.iter().any(is_renamed_filter),
|
|
"filter `{}` found, must NOT be present for filters tests",
|
|
TEST_FILTER_RENAME
|
|
);
|
|
|
|
let profiles = client.profiles().list().await?.profiles;
|
|
ensure!(
|
|
profiles.iter().map(String::as_str).any(is_required_profile),
|
|
"profile `{}` not found, required for profiles tests",
|
|
TEST_PROFILE
|
|
);
|
|
|
|
let studio_mode_enabled = client.ui().studio_mode_enabled().await?;
|
|
ensure!(
|
|
!studio_mode_enabled,
|
|
"studio mode enabled, required to be disabled for studio mode tests"
|
|
);
|
|
|
|
let recording_active = client.recording().status().await?.active;
|
|
ensure!(
|
|
!recording_active,
|
|
"recording active, required to be stopped for recording tests"
|
|
);
|
|
|
|
let virtual_cam_active = client.virtual_cam().status().await?;
|
|
ensure!(
|
|
!virtual_cam_active,
|
|
"virtual cam active, required to be stopped for outputs tests"
|
|
);
|
|
|
|
let replay_buffer_active = client.replay_buffer().status().await?;
|
|
ensure!(
|
|
!replay_buffer_active,
|
|
"replay buffer active, required to be stopped for outputs tests"
|
|
);
|
|
|
|
client
|
|
.scenes()
|
|
.set_current_program_scene(TEST_SCENE)
|
|
.await?;
|
|
|
|
Ok(())
|
|
}
|
|
|
|
fn is_required_scene(scene: &Scene) -> bool {
|
|
scene.name == TEST_SCENE
|
|
}
|
|
|
|
fn is_required_scene_2(scene: &Scene) -> bool {
|
|
scene.name == TEST_SCENE_2
|
|
}
|
|
|
|
fn is_renamed_scene(scene: &Scene) -> bool {
|
|
scene.name == TEST_SCENE_RENAME
|
|
}
|
|
|
|
fn is_created_scene(scene: &Scene) -> bool {
|
|
scene.name == TEST_SCENE_CREATE
|
|
}
|
|
|
|
fn is_required_group(group: &str) -> bool {
|
|
group == TEST_GROUP
|
|
}
|
|
|
|
fn is_required_text_input(input: &Input) -> bool {
|
|
input.name == TEST_TEXT && is_text_input(input)
|
|
}
|
|
|
|
fn is_required_text_2_input(input: &Input) -> bool {
|
|
input.name == TEST_TEXT_2 && is_text_input(input)
|
|
}
|
|
|
|
fn is_required_browser_input(input: &Input) -> bool {
|
|
input.name == TEST_BROWSER && is_browser_input(input)
|
|
}
|
|
|
|
fn is_required_media_input(input: &Input) -> bool {
|
|
input.name == TEST_MEDIA && is_media_input(input)
|
|
}
|
|
|
|
fn is_renamed_input(input: &Input) -> bool {
|
|
input.name == TEST_BROWSER_RENAME
|
|
}
|
|
|
|
fn is_text_input(input: &Input) -> bool {
|
|
input.kind == INPUT_KIND_TEXT_FT2
|
|
}
|
|
|
|
fn is_browser_input(input: &Input) -> bool {
|
|
input.kind == INPUT_KIND_BROWSER
|
|
}
|
|
|
|
fn is_media_input(input: &Input) -> bool {
|
|
input.kind == INPUT_KIND_VLC
|
|
}
|
|
|
|
fn is_required_filter(filter: &SourceFilter) -> bool {
|
|
filter.name == TEST_FILTER
|
|
}
|
|
|
|
fn is_filter_2(filter: &SourceFilter) -> bool {
|
|
filter.name == TEST_FILTER_2
|
|
}
|
|
|
|
fn is_renamed_filter(filter: &SourceFilter) -> bool {
|
|
filter.name == TEST_FILTER_RENAME
|
|
}
|
|
|
|
fn is_required_profile(profile: &str) -> bool {
|
|
profile == TEST_PROFILE
|
|
}
|
|
|
|
#[macro_export]
|
|
macro_rules! wait_for {
|
|
($expression:expr, $pattern:pat) => {{
|
|
use futures_util::stream::StreamExt;
|
|
|
|
while let Some(event) = $expression.next().await {
|
|
if matches!(event, $pattern) {
|
|
break;
|
|
}
|
|
}
|
|
}};
|
|
}
|