From 884f284263e243b3a8342ed1c728411fb438e4f9 Mon Sep 17 00:00:00 2001 From: Jagan Date: Tue, 25 Jul 2023 12:44:57 +0530 Subject: [PATCH] test(UI-tests): allow ignoring connector tests at runtime (#1766) Co-authored-by: Anji Reddy --- .github/testcases/ui_tests.json | 7 +- crates/router/tests/connectors/adyen_uk_ui.rs | 1 + .../tests/connectors/authorizedotnet_ui.rs | 5 + .../router/tests/connectors/globalpay_ui.rs | 1 + crates/router/tests/connectors/nuvei_ui.rs | 1 + crates/router/tests/connectors/paypal_ui.rs | 1 + crates/router/tests/connectors/selenium.rs | 117 +++++++++++++----- 7 files changed, 98 insertions(+), 35 deletions(-) diff --git a/.github/testcases/ui_tests.json b/.github/testcases/ui_tests.json index 135059803d..e3aca99bc9 100644 --- a/.github/testcases/ui_tests.json +++ b/.github/testcases/ui_tests.json @@ -1,4 +1,5 @@ { + "tests_to_ignore": [], "1": { "id": 1, "name": "stripe giropay", @@ -1107,7 +1108,7 @@ "id": 185, "name": "Adyen Touch n go", "connector": "adyen_uk", - "request": "{\"amount\":6540,\"currency\":\"MYR\",\"confirm\":true,\"capture_method\":\"automatic\",\"capture_on\":\"2022-09-10T10:11:12Z\",\"amount_to_capture\":6540,\"customer_id\":\"StripeCustomer\",\"email\":\"guest@example.com\",\"name\":\"John Doe\",\"phone\":\"999999999\",\"phone_country_code\":\"+1\",\"description\":\"Its my first payment request\",\"authentication_type\":\"no_three_ds\",\"return_url\":\"https://google.com/\",\"payment_method\":\"wallet\",\"payment_method_type\":\"touch_n_go\",\"payment_method_data\":{\"wallet\":{\"touch_n_go_redirect\":{}}}}" + "request": "{\"amount\":6540,\"currency\":\"MYR\",\"confirm\":true,\"capture_method\":\"automatic\",\"capture_on\":\"2022-09-10T10:11:12Z\",\"amount_to_capture\":6540,\"customer_id\":\"StripeCustomer\",\"email\":\"guest@example.com\",\"name\":\"John Doe\",\"phone\":\"999999999\",\"phone_country_code\":\"+1\",\"description\":\"Its my first payment request\",\"authentication_type\":\"no_three_ds\",\"return_url\":\"https://hs-payments-test.netlify.app/payments\",\"payment_method\":\"wallet\",\"payment_method_type\":\"touch_n_go\",\"payment_method_data\":{\"wallet\":{\"touch_n_go_redirect\":{}}}}" }, "186": { "id": 186, @@ -1203,7 +1204,7 @@ "id": 201, "name": "zen 3ds card ", "connector": "zen", - "request": "{\"amount\":101,\"currency\":\"PLN\",\"confirm\":true,\"business_country\":\"US\",\"business_label\":\"default\",\"amount_to_capture\":97,\"customer_id\":\"custhype1232\",\"capture_method\":\"automatic\",\"capture_on\":\"2022-09-10T10:11:12Z\",\"authentication_type\":\"three_ds\",\"return_url\":\"https://hs-payments-test.netlify.app/payments\",\"email\":\"something@gmail.com\",\"name\":\"Joseph Doe\",\"phone\":\"999999999\",\"phone_country_code\":\"+65\",\"description\":\"Its my first payment request\",\"statement_descriptor_name\":\"Juspay\",\"statement_descriptor_suffix\":\"Router\",\"payment_method\":\"card\",\"payment_method_type\":\"credit\",\"payment_method_data\":{\"card\":{\"card_number\":\"4242424242424242\",\"card_exp_month\":\"10\",\"card_exp_year\":\"2030\",\"card_holder_name\":\"joseph Doe\",\"card_cvc\":\"100\"}},\"billing\":{\"address\":{\"line1\":\"1467\",\"line2\":\"CA\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"CA\",\"zip\":\"94122\",\"country\":\"PL\",\"first_name\":\"joseph\",\"last_name\":\"Doe\"},\"phone\":{\"number\":\"8056594427\",\"country_code\":\"+91\"}},\"browser_info\":{\"user_agent\":\"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36\",\"accept_header\":\"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8\",\"language\":\"nl-NL\",\"color_depth\":24,\"screen_height\":723,\"screen_width\":1536,\"time_zone\":0,\"java_enabled\":true,\"java_script_enabled\":true,\"ip_address\":\"109.71.40.0\"},\"metadata\":{\"order_category\":\"applepay\"},\"order_details\":[{\"product_name\":\"Apple iphone 15\",\"quantity\":1,\"amount\":101,\"account_name\":\"transaction_processing\"}]}" + "request": "{\"amount\":101,\"currency\":\"PLN\",\"confirm\":true,\"business_country\":\"US\",\"business_label\":\"default\",\"amount_to_capture\":97,\"customer_id\":\"custhype1232\",\"capture_method\":\"automatic\",\"capture_on\":\"2022-09-10T10:11:12Z\",\"authentication_type\":\"three_ds\",\"return_url\":\"https://hs-payments-test.netlify.app/payments/\",\"email\":\"something@gmail.com\",\"name\":\"Joseph Doe\",\"phone\":\"999999999\",\"phone_country_code\":\"+65\",\"description\":\"Its my first payment request\",\"statement_descriptor_name\":\"Juspay\",\"statement_descriptor_suffix\":\"Router\",\"payment_method\":\"card\",\"payment_method_type\":\"credit\",\"payment_method_data\":{\"card\":{\"card_number\":\"4242424242424242\",\"card_exp_month\":\"10\",\"card_exp_year\":\"2030\",\"card_holder_name\":\"joseph Doe\",\"card_cvc\":\"100\"}},\"billing\":{\"address\":{\"line1\":\"1467\",\"line2\":\"CA\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"CA\",\"zip\":\"94122\",\"country\":\"PL\",\"first_name\":\"joseph\",\"last_name\":\"Doe\"},\"phone\":{\"number\":\"8056594427\",\"country_code\":\"+91\"}},\"browser_info\":{\"user_agent\":\"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36\",\"accept_header\":\"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8\",\"language\":\"nl-NL\",\"color_depth\":24,\"screen_height\":723,\"screen_width\":1536,\"time_zone\":0,\"java_enabled\":true,\"java_script_enabled\":true,\"ip_address\":\"109.71.40.0\"},\"metadata\":{\"order_category\":\"applepay\"},\"order_details\":[{\"product_name\":\"Apple iphone 15\",\"quantity\":1,\"amount\":101,\"account_name\":\"transaction_processing\"}]}" }, "202": { "id": "202", @@ -1341,7 +1342,7 @@ "id": 224, "name": "Oxxo", "connector": "adyen_uk", - "request": "{\"amount\":6540,\"currency\":\"IDR\",\"confirm\":true,\"capture_method\":\"automatic\",\"capture_on\":\"2022-09-10T10:11:12Z\",\"amount_to_capture\":6540,\"customer_id\":\"StripeCustomer\",\"email\":\"guest@example.com\",\"name\":\"John Doe\",\"phone\":\"999999999\",\"phone_country_code\":\"+1\",\"description\":\"Its my first payment request\",\"authentication_type\":\"no_three_ds\",\"return_url\":\"https://google.com/\",\"payment_method\":\"voucher\",\"payment_method_type\":\"oxxo\",\"payment_method_data\":{\"voucher\":{\"oxxo\":{}}}}" + "request": "{\"amount\":6540,\"currency\":\"MXN\",\"confirm\":true,\"capture_method\":\"automatic\",\"capture_on\":\"2022-09-10T10:11:12Z\",\"amount_to_capture\":6540,\"customer_id\":\"StripeCustomer\",\"email\":\"guest@example.com\",\"name\":\"John Doe\",\"phone\":\"999999999\",\"phone_country_code\":\"+1\",\"description\":\"Its my first payment request\",\"authentication_type\":\"no_three_ds\",\"return_url\":\"https://google.com/\",\"payment_method\":\"voucher\",\"payment_method_type\":\"oxxo\",\"payment_method_data\":{\"voucher\":{\"oxxo\":{}}}}" }, "225": { "id": 225, diff --git a/crates/router/tests/connectors/adyen_uk_ui.rs b/crates/router/tests/connectors/adyen_uk_ui.rs index b8fb90fb1a..e3b79e0ae2 100644 --- a/crates/router/tests/connectors/adyen_uk_ui.rs +++ b/crates/router/tests/connectors/adyen_uk_ui.rs @@ -247,6 +247,7 @@ async fn should_make_adyen_paypal_payment(web_driver: WebDriver) -> Result<(), W web_driver, &format!("{CHEKOUT_BASE_URL}/saved/202"), vec![ + Event::Trigger(Trigger::Click(By::Id("payment-submit-btn"))), Event::Assert(Assert::IsPresent("Google")), Event::Assert(Assert::ContainsAny( Selector::QueryParamStr, diff --git a/crates/router/tests/connectors/authorizedotnet_ui.rs b/crates/router/tests/connectors/authorizedotnet_ui.rs index d20831128c..b1bea20c1b 100644 --- a/crates/router/tests/connectors/authorizedotnet_ui.rs +++ b/crates/router/tests/connectors/authorizedotnet_ui.rs @@ -36,6 +36,11 @@ async fn should_make_paypal_payment(web_driver: WebDriver) -> Result<(), WebDriv web_driver, &format!("{CHEKOUT_BASE_URL}/saved/156"), vec![ + Event::EitherOr( + Assert::IsElePresent(By::Css(".reviewButton")), + vec![Event::Trigger(Trigger::Click(By::Css(".reviewButton")))], + vec![Event::Trigger(Trigger::Click(By::Id("payment-submit-btn")))], + ), Event::Assert(Assert::IsPresent("status")), Event::Assert(Assert::IsPresent("processing")), // This connector status will be processing for one day ], diff --git a/crates/router/tests/connectors/globalpay_ui.rs b/crates/router/tests/connectors/globalpay_ui.rs index bc7d831612..0efe538ec9 100644 --- a/crates/router/tests/connectors/globalpay_ui.rs +++ b/crates/router/tests/connectors/globalpay_ui.rs @@ -33,6 +33,7 @@ async fn should_make_globalpay_paypal_payment(driver: WebDriver) -> Result<(), W driver, &format!("{CHEKOUT_BASE_URL}/saved/46"), vec![ + Event::Trigger(Trigger::Click(By::Id("payment-submit-btn"))), Event::Assert(Assert::IsPresent("Google")), Event::Assert(Assert::ContainsAny( Selector::QueryParamStr, diff --git a/crates/router/tests/connectors/nuvei_ui.rs b/crates/router/tests/connectors/nuvei_ui.rs index a688535130..afe51bbde9 100644 --- a/crates/router/tests/connectors/nuvei_ui.rs +++ b/crates/router/tests/connectors/nuvei_ui.rs @@ -60,6 +60,7 @@ async fn should_make_nuvei_pypl_payment(c: WebDriver) -> Result<(), WebDriverErr c, &format!("{CHEKOUT_BASE_URL}/saved/5"), vec![ + Event::Trigger(Trigger::Click(By::Id("payment-submit-btn"))), Event::Assert(Assert::IsPresent("Google")), Event::Assert(Assert::ContainsAny( Selector::QueryParamStr, diff --git a/crates/router/tests/connectors/paypal_ui.rs b/crates/router/tests/connectors/paypal_ui.rs index ef999f7aff..3e9fc162dc 100644 --- a/crates/router/tests/connectors/paypal_ui.rs +++ b/crates/router/tests/connectors/paypal_ui.rs @@ -19,6 +19,7 @@ async fn should_make_paypal_paypal_wallet_payment( web_driver, &format!("{CHEKOUT_BASE_URL}/saved/21"), vec![ + Event::Trigger(Trigger::Click(By::Css(".reviewButton"))), Event::Assert(Assert::IsPresent("How Search works")), Event::Assert(Assert::ContainsAny( Selector::QueryParamStr, diff --git a/crates/router/tests/connectors/selenium.rs b/crates/router/tests/connectors/selenium.rs index a349cb2c2c..0f25cc3c9d 100644 --- a/crates/router/tests/connectors/selenium.rs +++ b/crates/router/tests/connectors/selenium.rs @@ -1,6 +1,13 @@ -use std::{collections::HashMap, env, io::Read, path::MAIN_SEPARATOR, time::Duration}; +use std::{ + collections::{HashMap, HashSet}, + env, + io::Read, + path::MAIN_SEPARATOR, + time::Duration, +}; use async_trait::async_trait; +use serde_json::json; use thirtyfour::{components::SelectElement, prelude::*, WebDriver}; use crate::connector_auth; @@ -54,26 +61,10 @@ pub static CHEKOUT_BASE_URL: &str = "https://hs-payments-test.netlify.app"; #[async_trait] pub trait SeleniumTest { fn get_saved_testcases(&self) -> serde_json::Value { - let env_value = env::var("CONNECTOR_TESTS_FILE_PATH").ok(); - if env_value.is_none() { - return serde_json::json!(""); - } - let path = env_value.unwrap(); - let mut file = &std::fs::File::open(path).expect("Failed to open file"); - let mut contents = String::new(); - file.read_to_string(&mut contents) - .expect("Failed to read file"); - - // Parse the JSON data - serde_json::from_str(&contents).expect("Failed to parse JSON") + get_saved_testcases() } fn get_configs(&self) -> connector_auth::ConnectorAuthentication { - let path = env::var("CONNECTOR_AUTH_FILE_PATH") - .expect("connector authentication file path not set"); - toml::from_str( - &std::fs::read_to_string(path).expect("connector authentication config file not found"), - ) - .expect("Failed to read connector authentication config file") + get_configs() } async fn retry_click( &self, @@ -496,8 +487,15 @@ pub trait SeleniumTest { ) -> Result<(), WebDriverError> { let pypl_url = url.to_string(); // To support failure retries - self.execute_paypal_steps(web_driver.clone(), &pypl_url, actions.clone()) - .await + let result = self + .execute_paypal_steps(web_driver.clone(), &pypl_url, actions.clone()) + .await; + if result.is_err() { + self.execute_paypal_steps(web_driver.clone(), &pypl_url, actions.clone()) + .await + } else { + result + } } async fn execute_paypal_steps( &self, @@ -528,24 +526,21 @@ pub trait SeleniumTest { .unwrap(), ); let mut pypl_actions = vec![ - Event::EitherOr( - Assert::IsPresent("Forgot email?"), + Event::Trigger(Trigger::Sleep(8)), + Event::RunIf( + Assert::IsPresentNow("Enter your email address to get started"), vec![ Event::Trigger(Trigger::SendKeys(By::Id("email"), email)), Event::Trigger(Trigger::Click(By::Id("btnNext"))), - Event::Trigger(Trigger::SendKeys(By::Id("password"), pass)), - Event::Trigger(Trigger::Click(By::Id("btnLogin"))), ], + ), + Event::RunIf( + Assert::IsPresentNow("Password"), vec![ Event::Trigger(Trigger::SendKeys(By::Id("password"), pass)), Event::Trigger(Trigger::Click(By::Id("btnLogin"))), ], ), - Event::EitherOr( - Assert::IsPresent("See Offers and Apply for PayPal Credit"), - vec![Event::Trigger(Trigger::Click(By::Css(".reviewButton")))], - vec![Event::Trigger(Trigger::Click(By::Id("payment-submit-btn")))], - ), ]; pypl_actions.extend(actions); self.complete_actions(&web_driver, pypl_actions).await @@ -592,7 +587,7 @@ pub trait SeleniumTest { Assert::IsPresent("Please enter your password"), vec![ Event::Trigger(Trigger::SendKeys(By::Css("input[name='password']"), pass)), - Event::Trigger(Trigger::Click(By::Css("button.a_l.a_i.a_n.a_m"))), + Event::Trigger(Trigger::Click(By::Css("button[type='submit']"))), ], vec![ Event::Trigger(Trigger::SendKeys( @@ -618,6 +613,10 @@ async fn is_text_present_now(driver: &WebDriver, key: &str) -> WebDriverResult WebDriverResult { @@ -673,10 +672,26 @@ macro_rules! tester_inner { }}; } +#[macro_export] +macro_rules! function { + () => {{ + fn f() {} + fn type_name_of(_: T) -> &'static str { + std::any::type_name::() + } + let name = type_name_of(f); + &name[..name.len() - 3] + }}; +} + #[macro_export] macro_rules! tester { ($f:ident) => {{ - use $crate::tester_inner; + use $crate::{function, tester_inner}; + let test_name = format!("{:?}", function!()); + if (should_ignore_test(&test_name)) { + return; + } let browser = get_browser(); let url = make_url(&browser); let caps = make_capabilities(&browser); @@ -684,6 +699,44 @@ macro_rules! tester { }}; } +fn get_saved_testcases() -> serde_json::Value { + let env_value = env::var("CONNECTOR_TESTS_FILE_PATH").ok(); + if env_value.is_none() { + return serde_json::json!(""); + } + let path = env_value.unwrap(); + let mut file = &std::fs::File::open(path).expect("Failed to open file"); + let mut contents = String::new(); + file.read_to_string(&mut contents) + .expect("Failed to read file"); + + // Parse the JSON data + serde_json::from_str(&contents).expect("Failed to parse JSON") +} +fn get_configs() -> connector_auth::ConnectorAuthentication { + let path = + env::var("CONNECTOR_AUTH_FILE_PATH").expect("connector authentication file path not set"); + toml::from_str( + &std::fs::read_to_string(path).expect("connector authentication config file not found"), + ) + .expect("Failed to read connector authentication config file") +} + +pub fn should_ignore_test(name: &str) -> bool { + let conf = get_saved_testcases() + .get("tests_to_ignore") + .unwrap_or(&json!([])) + .clone(); + let tests_to_ignore: HashSet = + serde_json::from_value(conf).unwrap_or_else(|_| HashSet::new()); + // let tests_to_ignore = conf.automation_configs.unwrap().tests_to_ignore.unwrap_or_else(|| HashSet::new()); + let modules: Vec<_> = name.split("::").collect(); + let file_match = format!("{}::*", <&str>::clone(&modules[1])); + let module_name = modules[1..3].join("::"); + // Ignore if it matches patterns like nuvei_ui::*, nuvei_ui::should_make_nuvei_eps_payment_test + tests_to_ignore.contains(&file_match) || tests_to_ignore.contains(&module_name) +} + pub fn get_browser() -> String { "firefox".to_string() }