use std::time::Duration;
use crate::step::{StepError, StepParam};
use crate::world::BrowserWorld;
use ferridriver_bdd_macros::step;
use ferridriver_test::expect::{self, AssertionFailure, expect};
fn to_step_err(e: AssertionFailure) -> StepError {
StepError {
message: e.message,
diff: e.diff.map(|d| (d, String::new())),
pending: false,
}
}
#[step("I wait {int} millisecond(s)")]
async fn wait_ms(world: &mut BrowserWorld, ms: i64) {
tokio::time::sleep(Duration::from_millis(ms as u64)).await;
}
#[step("I wait {int} second(s)")]
async fn wait_seconds(world: &mut BrowserWorld, seconds: i64) {
tokio::time::sleep(Duration::from_secs(seconds as u64)).await;
}
#[step("I wait for {string}")]
async fn wait_for_selector(world: &mut BrowserWorld, selector: String) {
let locator = world.page().locator(&selector, None);
expect(&locator).to_be_attached().await.map_err(to_step_err)?;
}
#[step("I wait for {string} to contain {string}")]
async fn wait_for_text(world: &mut BrowserWorld, selector: String, expected: String) {
let locator = world.page().locator(&selector, None);
expect(&locator)
.to_contain_text(expected.as_str())
.await
.map_err(to_step_err)?;
}
#[step("I wait for {string} to be visible")]
async fn wait_for_visible(world: &mut BrowserWorld, selector: String) {
let locator = world.page().locator(&selector, None);
expect(&locator).to_be_visible().await.map_err(to_step_err)?;
}
#[step("I wait for {string} to be hidden")]
async fn wait_for_hidden(world: &mut BrowserWorld, selector: String) {
let locator = world.page().locator(&selector, None);
expect(&locator).to_be_hidden().await.map_err(to_step_err)?;
}
#[step(regex = r#"^within (\d+) seconds?, (.+)$"#)]
async fn within_seconds(world: &mut BrowserWorld, timeout_secs: String, inner_step: String) {
let timeout_secs: u64 = timeout_secs.parse().map_err(|e| StepError {
message: format!("invalid timeout: {e}"),
diff: None,
pending: false,
})?;
let timeout = Duration::from_secs(timeout_secs);
let base_fixtures = world.fixtures().clone();
let registry = world.registry_arc();
let registry = registry.ok_or_else(|| StepError {
message: "step registry not available for retry step".into(),
diff: None,
pending: false,
})?;
let step_match = registry.find_match(&inner_step).map_err(|e| StepError {
message: format!("inner step not found: {e}"),
diff: None,
pending: false,
})?;
let handler = step_match.def.handler.clone();
let params = step_match.params;
expect::to_pass(timeout, || {
let handler = handler.clone();
let params = params.clone();
let base_fixtures = base_fixtures.clone();
let registry = registry.clone();
async move {
let mut temp_world = BrowserWorld::new(base_fixtures);
temp_world.set_registry(registry);
handler(&mut temp_world, params, None, None)
.await
.map_err(|e| AssertionFailure::new(e.message, None))
}
})
.await
.map_err(to_step_err)?;
}