Skip to content

Commit

Permalink
test(UI-tests): allow ignoring connector tests at runtime (#1766)
Browse files Browse the repository at this point in the history
Co-authored-by: Anji Reddy <[email protected]>
  • Loading branch information
jagan-jaya and anji-reddy-j authored Jul 25, 2023
1 parent 37a0651 commit 884f284
Show file tree
Hide file tree
Showing 7 changed files with 98 additions and 35 deletions.
7 changes: 4 additions & 3 deletions .github/testcases/ui_tests.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"tests_to_ignore": [],
"1": {
"id": 1,
"name": "stripe giropay",
Expand Down Expand Up @@ -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\":\"[email protected]\",\"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\":\"[email protected]\",\"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,
Expand Down Expand Up @@ -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\":\"[email protected]\",\"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\":\"[email protected]\",\"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",
Expand Down Expand Up @@ -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\":\"[email protected]\",\"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\":\"[email protected]\",\"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,
Expand Down
1 change: 1 addition & 0 deletions crates/router/tests/connectors/adyen_uk_ui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
5 changes: 5 additions & 0 deletions crates/router/tests/connectors/authorizedotnet_ui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
],
Expand Down
1 change: 1 addition & 0 deletions crates/router/tests/connectors/globalpay_ui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
1 change: 1 addition & 0 deletions crates/router/tests/connectors/nuvei_ui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
1 change: 1 addition & 0 deletions crates/router/tests/connectors/paypal_ui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
117 changes: 85 additions & 32 deletions crates/router/tests/connectors/selenium.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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(
Expand All @@ -618,6 +613,10 @@ async fn is_text_present_now(driver: &WebDriver, key: &str) -> WebDriverResult<b
xpath.push_str(key);
xpath.push_str("')]");
let result = driver.find(By::XPath(&xpath)).await?;
let display: &str = &result.css_value("display").await?;
if display.is_empty() || display == "none" {
return Err(WebDriverError::CustomError("Element is hidden".to_string()));
}
result.is_present().await
}
async fn is_text_present(driver: &WebDriver, key: &str) -> WebDriverResult<bool> {
Expand Down Expand Up @@ -673,17 +672,71 @@ macro_rules! tester_inner {
}};
}

#[macro_export]
macro_rules! function {
() => {{
fn f() {}
fn type_name_of<T>(_: T) -> &'static str {
std::any::type_name::<T>()
}
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);
tester_inner!($f, WebDriver::new(url, caps));
}};
}

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<String> =
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()
}
Expand Down

0 comments on commit 884f284

Please sign in to comment.