test(selenium): read config from CONNECTOR_AUTH_FILE_PATH environment variable and fix bugs in UI tests (#1225)

Co-authored-by: AkshayaFoiger <akshaya.shankar@juspay.in>
Co-authored-by: Sanchith Hegde <22217505+SanchithHegde@users.noreply.github.com>
This commit is contained in:
Jagan
2023-06-05 13:00:00 +05:30
committed by GitHub
parent 10691c5fce
commit d9a16ed5ab
13 changed files with 738 additions and 118 deletions

View File

@ -15,7 +15,6 @@ pub enum IncomingWebhookEvent {
EventNotSupported,
SourceChargeable,
SourceTransactionCreated,
ChargeSucceeded,
RefundFailure,
RefundSuccess,
DisputeOpened,
@ -60,7 +59,6 @@ impl From<IncomingWebhookEvent> for WebhookFlow {
IncomingWebhookEvent::EndpointVerification => Self::ReturnResponse,
IncomingWebhookEvent::SourceChargeable
| IncomingWebhookEvent::SourceTransactionCreated => Self::BankTransfer,
IncomingWebhookEvent::ChargeSucceeded => Self::Payment,
}
}
}

View File

@ -75,6 +75,15 @@ pub struct NuveiPaymentsRequest {
pub checksum: String,
pub billing_address: Option<BillingAddress>,
pub related_transaction_id: Option<String>,
pub url_details: Option<UrlDetails>,
}
#[derive(Debug, Serialize, Default)]
#[serde(rename_all = "camelCase")]
pub struct UrlDetails {
pub success_url: String,
pub failure_url: String,
pub pending_url: String,
}
#[derive(Debug, Serialize, Default)]
@ -676,12 +685,18 @@ impl<F>
capture_method: item.request.capture_method,
..Default::default()
})?;
let return_url = item.request.get_return_url()?;
Ok(Self {
is_rebilling: request_data.is_rebilling,
user_token_id: request_data.user_token_id,
related_transaction_id: request_data.related_transaction_id,
payment_option: request_data.payment_option,
billing_address: request_data.billing_address,
url_details: Some(UrlDetails {
success_url: return_url.clone(),
failure_url: return_url.clone(),
pending_url: return_url,
}),
..request
})
}
@ -1017,6 +1032,7 @@ pub enum NuveiTransactionStatus {
Declined,
Error,
Redirect,
Pending,
#[default]
Processing,
}
@ -1100,7 +1116,9 @@ fn get_payment_status(response: &NuveiPaymentsResponse) -> enums::AttemptStatus
_ => enums::AttemptStatus::Failure,
}
}
NuveiTransactionStatus::Processing => enums::AttemptStatus::Pending,
NuveiTransactionStatus::Processing | NuveiTransactionStatus::Pending => {
enums::AttemptStatus::Pending
}
NuveiTransactionStatus::Redirect => enums::AttemptStatus::AuthenticationPending,
},
None => match response.status {
@ -1253,7 +1271,9 @@ impl From<NuveiTransactionStatus> for enums::RefundStatus {
match item {
NuveiTransactionStatus::Approved => Self::Success,
NuveiTransactionStatus::Declined | NuveiTransactionStatus::Error => Self::Failure,
NuveiTransactionStatus::Processing | NuveiTransactionStatus::Redirect => Self::Pending,
NuveiTransactionStatus::Processing
| NuveiTransactionStatus::Pending
| NuveiTransactionStatus::Redirect => Self::Pending,
}
}
}

View File

@ -1645,14 +1645,8 @@ impl api::IncomingWebhook for Stripe {
Ok(match details.event_data.event_object.object {
stripe::WebhookEventObjectType::PaymentIntent
| stripe::WebhookEventObjectType::Charge => {
api_models::webhooks::ObjectReferenceId::PaymentId(
api_models::payments::PaymentIdType::ConnectorTransactionId(
details.event_data.event_object.id,
),
)
}
stripe::WebhookEventObjectType::Dispute => {
| stripe::WebhookEventObjectType::Charge
| stripe::WebhookEventObjectType::Dispute => {
api_models::webhooks::ObjectReferenceId::PaymentId(
api_models::payments::PaymentIdType::ConnectorTransactionId(
details
@ -1692,7 +1686,9 @@ impl api::IncomingWebhook for Stripe {
stripe::WebhookEventType::SourceChargeable => {
api::IncomingWebhookEvent::SourceChargeable
}
stripe::WebhookEventType::ChargeSucceeded => api::IncomingWebhookEvent::ChargeSucceeded,
stripe::WebhookEventType::ChargeSucceeded => {
api::IncomingWebhookEvent::PaymentIntentSuccess
}
stripe::WebhookEventType::DisputeCreated => api::IncomingWebhookEvent::DisputeOpened,
stripe::WebhookEventType::DisputeClosed => api::IncomingWebhookEvent::DisputeCancelled,
stripe::WebhookEventType::DisputeUpdated => api::IncomingWebhookEvent::try_from(

View File

@ -1399,11 +1399,11 @@ pub struct PaymentIntentResponse {
pub id: String,
pub object: String,
pub amount: i64,
pub amount_received: i64,
pub amount_capturable: i64,
pub amount_received: Option<i64>,
pub amount_capturable: Option<i64>,
pub currency: String,
pub status: StripePaymentStatus,
pub client_secret: Secret<String>,
pub client_secret: Option<Secret<String>>,
pub created: i32,
pub customer: Option<String>,
pub payment_method: Option<String>,
@ -1519,7 +1519,7 @@ impl From<SetupIntentResponse> for PaymentIntentResponse {
id: value.id,
object: value.object,
status: value.status,
client_secret: value.client_secret,
client_secret: Some(value.client_secret),
customer: value.customer,
description: None,
statement_descriptor: value.statement_descriptor,
@ -1619,7 +1619,7 @@ impl<F, T>
connector_metadata,
network_txn_id,
}),
amount_captured: Some(item.response.amount_received),
amount_captured: item.response.amount_received,
..item.data
})
}
@ -1707,7 +1707,7 @@ impl<F, T>
Ok(Self {
status: enums::AttemptStatus::from(item.response.status.to_owned()),
response,
amount_captured: Some(item.response.amount_received),
amount_captured: item.response.amount_received,
..item.data
})
}

View File

@ -5,29 +5,35 @@ use crate::{selenium::*, tester};
struct AdyenSeleniumTest;
impl SeleniumTest for AdyenSeleniumTest {}
impl SeleniumTest for AdyenSeleniumTest {
fn get_connector_name(&self) -> String {
"adyen_uk".to_string()
}
}
async fn should_make_adyen_gpay_payment(c: WebDriver) -> Result<(), WebDriverError> {
let conn = AdyenSeleniumTest {};
let pub_key = conn.get_configs().adyen_uk.unwrap().key1;
conn.make_gpay_payment(c,
&format!("{CHEKOUT_BASE_URL}/gpay?gatewayname=adyen&gatewaymerchantid=JuspayDEECOM&amount=70.00&country=US&currency=USD"),
&format!("{CHEKOUT_BASE_URL}/gpay?gatewayname=adyen&gatewaymerchantid={pub_key}&amount=70.00&country=US&currency=USD"),
vec![
Event::Assert(Assert::IsPresent("succeeded")),
Event::Assert(Assert::IsPresent("processing")),
]).await?;
Ok(())
}
async fn should_make_adyen_gpay_mandate_payment(c: WebDriver) -> Result<(), WebDriverError> {
let conn = AdyenSeleniumTest {};
let pub_key = conn.get_configs().adyen_uk.unwrap().key1;
conn.make_gpay_payment(c,
&format!("{CHEKOUT_BASE_URL}/gpay?gatewayname=adyen&gatewaymerchantid=JuspayDEECOM&amount=70.00&country=US&currency=USD&mandate_data[customer_acceptance][acceptance_type]=offline&mandate_data[customer_acceptance][accepted_at]=1963-05-03T04:07:52.723Z&mandate_data[customer_acceptance][online][ip_address]=127.0.0.1&mandate_data[customer_acceptance][online][user_agent]=amet%20irure%20esse&mandate_data[mandate_type][multi_use][amount]=7000&mandate_data[mandate_type][multi_use][currency]=USD"),
&format!("{CHEKOUT_BASE_URL}/gpay?gatewayname=adyen&gatewaymerchantid={pub_key}&amount=70.00&country=US&currency=USD&mandate_data[customer_acceptance][acceptance_type]=offline&mandate_data[customer_acceptance][accepted_at]=1963-05-03T04:07:52.723Z&mandate_data[customer_acceptance][online][ip_address]=127.0.0.1&mandate_data[customer_acceptance][online][user_agent]=amet%20irure%20esse&mandate_data[mandate_type][multi_use][amount]=7000&mandate_data[mandate_type][multi_use][currency]=USD"),
vec![
Event::Assert(Assert::IsPresent("succeeded")),
Event::Assert(Assert::IsPresent("processing")),
Event::Assert(Assert::IsPresent("Mandate ID")),
Event::Assert(Assert::IsPresent("man_")),// mandate id starting with man_
Event::Trigger(Trigger::Click(By::Id("pm-mandate-btn"))),
Event::Trigger(Trigger::Click(By::Css("#pm-mandate-btn a"))),
Event::Trigger(Trigger::Click(By::Id("pay-with-mandate-btn"))),
Event::Assert(Assert::IsPresent("succeeded")),
Event::Assert(Assert::IsPresent("processing")),
]).await?;
Ok(())
}
@ -36,15 +42,16 @@ async fn should_make_adyen_gpay_zero_dollar_mandate_payment(
c: WebDriver,
) -> Result<(), WebDriverError> {
let conn = AdyenSeleniumTest {};
let pub_key = conn.get_configs().adyen_uk.unwrap().key1;
conn.make_gpay_payment(c,
&format!("{CHEKOUT_BASE_URL}/gpay?gatewayname=adyen&gatewaymerchantid=JuspayDEECOM&amount=0.00&country=US&currency=USD&mandate_data[customer_acceptance][acceptance_type]=offline&mandate_data[customer_acceptance][accepted_at]=1963-05-03T04:07:52.723Z&mandate_data[customer_acceptance][online][ip_address]=127.0.0.1&mandate_data[customer_acceptance][online][user_agent]=amet%20irure%20esse&mandate_data[mandate_type][multi_use][amount]=700&mandate_data[mandate_type][multi_use][currency]=USD"),
&format!("{CHEKOUT_BASE_URL}/gpay?gatewayname=adyen&gatewaymerchantid={pub_key}&amount=0.00&country=US&currency=USD&mandate_data[customer_acceptance][acceptance_type]=offline&mandate_data[customer_acceptance][accepted_at]=1963-05-03T04:07:52.723Z&mandate_data[customer_acceptance][online][ip_address]=127.0.0.1&mandate_data[customer_acceptance][online][user_agent]=amet%20irure%20esse&mandate_data[mandate_type][multi_use][amount]=700&mandate_data[mandate_type][multi_use][currency]=USD"),
vec![
Event::Assert(Assert::IsPresent("succeeded")),
Event::Assert(Assert::IsPresent("processing")),
Event::Assert(Assert::IsPresent("Mandate ID")),
Event::Assert(Assert::IsPresent("man_")),// mandate id starting with man_
Event::Trigger(Trigger::Click(By::Id("pm-mandate-btn"))),
Event::Trigger(Trigger::Click(By::Css("#pm-mandate-btn a"))),
Event::Trigger(Trigger::Click(By::Id("pay-with-mandate-btn"))),
Event::Assert(Assert::IsPresent("succeeded")),
Event::Assert(Assert::IsPresent("processing")),
]).await?;
Ok(())
}
@ -67,12 +74,12 @@ async fn should_make_adyen_klarna_mandate_payment(c: WebDriver) -> Result<(), We
]
),
Event::Trigger(Trigger::SwitchTab(Position::Prev)),
Event::Assert(Assert::IsPresent("succeeded")),
Event::Assert(Assert::IsPresent("processing")),
Event::Assert(Assert::IsPresent("Mandate ID")),
Event::Assert(Assert::IsPresent("man_")),// mandate id starting with man_
Event::Trigger(Trigger::Click(By::Id("pm-mandate-btn"))),
Event::Trigger(Trigger::Click(By::Css("#pm-mandate-btn a"))),
Event::Trigger(Trigger::Click(By::Id("pay-with-mandate-btn"))),
Event::Assert(Assert::IsPresent("succeeded")),
Event::Assert(Assert::IsPresent("processing")),
]).await?;
Ok(())
}

View File

@ -1,12 +1,13 @@
use std::env;
use router::types::ConnectorAuthType;
use serde::Deserialize;
use serde::{Deserialize, Serialize};
#[derive(Debug, Deserialize, Clone)]
pub(crate) struct ConnectorAuthentication {
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct ConnectorAuthentication {
pub aci: Option<BodyKey>,
pub adyen: Option<BodyKey>,
pub adyen_uk: Option<BodyKey>,
pub airwallex: Option<BodyKey>,
pub authorizedotnet: Option<BodyKey>,
pub bambora: Option<BodyKey>,
@ -35,10 +36,13 @@ pub(crate) struct ConnectorAuthentication {
pub rapyd: Option<BodyKey>,
pub shift4: Option<HeaderKey>,
pub stripe: Option<HeaderKey>,
pub stripe_au: Option<HeaderKey>,
pub stripe_uk: Option<HeaderKey>,
pub trustpay: Option<SignatureKey>,
pub worldpay: Option<BodyKey>,
pub worldline: Option<SignatureKey>,
pub zen: Option<HeaderKey>,
pub automation_configs: Option<AutomationConfigs>,
}
impl ConnectorAuthentication {
@ -55,8 +59,8 @@ impl ConnectorAuthentication {
}
}
#[derive(Debug, Deserialize, Clone)]
pub(crate) struct HeaderKey {
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct HeaderKey {
pub api_key: String,
}
@ -68,8 +72,8 @@ impl From<HeaderKey> for ConnectorAuthType {
}
}
#[derive(Debug, Deserialize, Clone)]
pub(crate) struct BodyKey {
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct BodyKey {
pub api_key: String,
pub key1: String,
}
@ -83,8 +87,8 @@ impl From<BodyKey> for ConnectorAuthType {
}
}
#[derive(Debug, Deserialize, Clone)]
pub(crate) struct SignatureKey {
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct SignatureKey {
pub api_key: String,
pub key1: String,
pub api_secret: String,
@ -100,8 +104,8 @@ impl From<SignatureKey> for ConnectorAuthType {
}
}
#[derive(Debug, Deserialize, Clone)]
pub(crate) struct MultiAuthKey {
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct MultiAuthKey {
pub api_key: String,
pub key1: String,
pub api_secret: String,
@ -118,3 +122,20 @@ impl From<MultiAuthKey> for ConnectorAuthType {
}
}
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct AutomationConfigs {
pub hs_base_url: Option<String>,
pub hs_api_key: Option<String>,
pub hs_test_browser: Option<String>,
pub chrome_profile_path: Option<String>,
pub firefox_profile_path: Option<String>,
pub pypl_email: Option<String>,
pub pypl_pass: Option<String>,
pub gmail_email: Option<String>,
pub gmail_pass: Option<String>,
pub configs_url: Option<String>,
pub stripe_pub_key: Option<String>,
pub testcases_path: Option<String>,
pub run_minimum_steps: Option<bool>,
}

View File

@ -7,7 +7,7 @@
mod aci;
mod adyen;
mod adyen_ui;
mod adyen_uk_ui;
mod airwallex;
mod authorizedotnet;
mod bambora;
@ -35,6 +35,7 @@ mod opennode;
mod payeezy;
mod paypal;
mod payu;
mod payu_ui;
mod rapyd;
mod selenium;
mod shift4;
@ -43,5 +44,6 @@ mod stripe_ui;
mod trustpay;
mod utils;
mod worldline;
mod worldline_ui;
mod worldpay;
mod zen;

View File

@ -5,7 +5,11 @@ use crate::{selenium::*, tester};
struct NuveiSeleniumTest;
impl SeleniumTest for NuveiSeleniumTest {}
impl SeleniumTest for NuveiSeleniumTest {
fn get_connector_name(&self) -> String {
"nuvei".to_string()
}
}
async fn should_make_nuvei_3ds_payment(c: WebDriver) -> Result<(), WebDriverError> {
let conn = NuveiSeleniumTest {};
@ -27,14 +31,13 @@ async fn should_make_nuvei_3ds_payment(c: WebDriver) -> Result<(), WebDriverErro
async fn should_make_nuvei_3ds_mandate_payment(c: WebDriver) -> Result<(), WebDriverError> {
let conn = NuveiSeleniumTest {};
conn.make_redirection_payment(c, vec![
Event::Trigger(Trigger::Goto(&format!("{CHEKOUT_BASE_URL}/card?cname=CL-BRW1&ccnum=4000027891380961&expmonth=10&expyear=25&cvv=123&amount=200&country=US&currency=USD&setup_future_usage=off_session&mandate_data[customer_acceptance][acceptance_type]=offline&mandate_data[customer_acceptance][accepted_at]=1963-05-03T04:07:52.723Z&mandate_data[customer_acceptance][online][ip_address]=in%20sit&mandate_data[customer_acceptance][online][user_agent]=amet%20irure%20esse&mandate_data[mandate_type][multi_use][amount]=7000&mandate_data[mandate_type][multi_use][currency]=USD&mandate_data[mandate_type][multi_use][start_date]=2022-09-10T00:00:00Z&mandate_data[mandate_type][multi_use][end_date]=2023-09-10T00:00:00Z&mandate_data[mandate_type][multi_use][metadata][frequency]=13"))),
Event::Trigger(Trigger::Goto(&format!("{CHEKOUT_BASE_URL}/card?cname=CL-BRW1&ccnum=4000027891380961&expmonth=10&expyear=25&cvv=123&amount=200&country=US&currency=USD&setup_future_usage=off_session&mandate_data[customer_acceptance][acceptance_type]=offline&mandate_data[customer_acceptance][accepted_at]=1963-05-03T04:07:52.723Z&mandate_data[customer_acceptance][online][ip_address]=in%20sit&mandate_data[customer_acceptance][online][user_agent]=amet%20irure%20esse&mandate_data[mandate_type][multi_use][amount]=7000&mandate_data[mandate_type][multi_use][currency]=USD&mandate_data[mandate_type][multi_use][start_date]=2022-09-10T00:00:00Z&mandate_data[mandate_type][multi_use][end_date]=2023-09-10T00:00:00Z&mandate_data[mandate_type][multi_use][metadata][frequency]=13&return_url={CHEKOUT_BASE_URL}/payments"))),
Event::Trigger(Trigger::Click(By::Id("card-submit-btn"))),
Event::Trigger(Trigger::Query(By::ClassName("title"))),
Event::Assert(Assert::Eq(Selector::Title, "ThreeDS ACS Emulator - Challenge Page")),
Event::Trigger(Trigger::Click(By::Id("btn1"))),
Event::Trigger(Trigger::Click(By::Id("btn5"))),
Event::Assert(Assert::IsPresent("Google")),
Event::Assert(Assert::Contains(Selector::QueryParamStr, "status=succeeded")),
Event::Assert(Assert::IsPresent("succeeded")),
Event::Assert(Assert::IsPresent("man_")),//mandate id prefix is present
]).await?;
@ -56,9 +59,13 @@ async fn should_make_nuvei_pypl_payment(c: WebDriver) -> Result<(), WebDriverErr
conn.make_paypal_payment(
c,
&format!("{CHEKOUT_BASE_URL}/paypal-redirect?amount=12.00&country=US&currency=USD"),
vec![Event::Assert(Assert::IsPresent(
"Your transaction has been successfully executed.",
))],
vec![
Event::Assert(Assert::IsPresent("Google")),
Event::Assert(Assert::ContainsAny(
Selector::QueryParamStr,
vec!["status=succeeded"],
)),
],
)
.await?;
Ok(())
@ -82,7 +89,8 @@ async fn should_make_nuvei_giropay_payment(c: WebDriver) -> Result<(), WebDriver
Event::Trigger(Trigger::Sleep(5)),
Event::Trigger(Trigger::SwitchTab(Position::Next)),
Event::Assert(Assert::IsPresent("Sicher bezahlt!")),
Event::Assert(Assert::IsPresent("Your transaction")) // Transaction succeeds sometimes and pending sometimes
Event::Assert(Assert::IsPresent("Google")),
Event::Assert(Assert::ContainsAny(Selector::QueryParamStr, vec!["status=succeeded", "status=processing"]))
]).await?;
Ok(())
}
@ -98,7 +106,8 @@ async fn should_make_nuvei_ideal_payment(c: WebDriver) -> Result<(), WebDriverEr
Event::Assert(Assert::IsPresent("IDEALFORTIS")),
Event::Trigger(Trigger::Sleep(5)),
Event::Trigger(Trigger::Click(By::Id("ctl00_mainContent_btnGo"))),
Event::Assert(Assert::IsPresent("Your transaction")),// Transaction succeeds sometimes and pending sometimes
Event::Assert(Assert::IsPresent("Google")),
Event::Assert(Assert::ContainsAny(Selector::QueryParamStr, vec!["status=succeeded", "status=processing"]))
]).await?;
Ok(())
}
@ -111,7 +120,8 @@ async fn should_make_nuvei_sofort_payment(c: WebDriver) -> Result<(), WebDriverE
Event::Assert(Assert::IsPresent("SOFORT")),
Event::Trigger(Trigger::ChangeQueryParam("sender_holder", "John Doe")),
Event::Trigger(Trigger::Click(By::Id("ctl00_mainContent_btnGo"))),
Event::Assert(Assert::IsPresent("Your transaction")),// Transaction succeeds sometimes and pending sometimes
Event::Assert(Assert::IsPresent("Google")),
Event::Assert(Assert::ContainsAny(Selector::QueryParamStr, vec!["status=succeeded", "status=processing"]))
]).await?;
Ok(())
}
@ -127,7 +137,8 @@ async fn should_make_nuvei_eps_payment(c: WebDriver) -> Result<(), WebDriverErro
Event::Assert(Assert::IsPresent("Simulator")),
Event::Trigger(Trigger::SelectOption(By::Css("select[name='result']"), "Succeeded")),
Event::Trigger(Trigger::Click(By::Id("submitbutton"))),
Event::Assert(Assert::IsPresent("Your transaction")),// Transaction succeeds sometimes and pending sometimes
Event::Assert(Assert::IsPresent("Google")),
Event::Assert(Assert::ContainsAny(Selector::QueryParamStr, vec!["status=succeeded", "status=processing"]))
]).await?;
Ok(())
}

View File

@ -0,0 +1,56 @@
use serial_test::serial;
use thirtyfour::{prelude::*, WebDriver};
use crate::{selenium::*, tester};
struct PayUSeleniumTest;
impl SeleniumTest for PayUSeleniumTest {
fn get_connector_name(&self) -> String {
"payu".to_string()
}
}
async fn should_make_no_3ds_card_payment(c: WebDriver) -> Result<(), WebDriverError> {
let conn = PayUSeleniumTest {};
conn.make_redirection_payment(
c,
vec![
Event::Trigger(Trigger::Goto(&format!("{CHEKOUT_BASE_URL}/saved/72"))),
Event::Trigger(Trigger::Click(By::Id("card-submit-btn"))),
Event::Trigger(Trigger::Sleep(1)),
Event::Assert(Assert::IsPresent("status")),
Event::Assert(Assert::IsPresent("processing")),
],
)
.await?;
Ok(())
}
async fn should_make_gpay_payment(c: WebDriver) -> Result<(), WebDriverError> {
let conn = PayUSeleniumTest {};
conn.make_redirection_payment(
c,
vec![
Event::Trigger(Trigger::Goto(&format!("{CHEKOUT_BASE_URL}/saved/77"))),
Event::Trigger(Trigger::Click(By::Id("card-submit-btn"))),
Event::Trigger(Trigger::Sleep(1)),
Event::Assert(Assert::IsPresent("status")),
Event::Assert(Assert::IsPresent("processing")),
],
)
.await?;
Ok(())
}
#[test]
#[serial]
fn should_make_no_3ds_card_payment_test() {
tester!(should_make_no_3ds_card_payment);
}
#[test]
#[serial]
fn should_make_gpay_payment_test() {
tester!(should_make_gpay_payment);
}

View File

@ -115,3 +115,13 @@ api_key = "API Key"
api_key = "Application API KEY"
api_secret = "Application Identifier"
key1 = "Business Identifier"
[automation_configs]
hs_base_url="http://localhost:8080"
hs_test_browser="firefox"
chrome_profile_path=""
firefox_profile_path=""
pypl_email=""
pypl_pass=""
gmail_email=""
gmail_pass=""

View File

@ -4,6 +4,9 @@ use actix_web::cookie::SameSite;
use async_trait::async_trait;
use thirtyfour::{components::SelectElement, prelude::*, WebDriver};
use crate::connector_auth;
#[derive(Clone)]
pub enum Event<'a> {
RunIf(Assert<'a>, Vec<Event<'a>>),
EitherOr(Assert<'a>, Vec<Event<'a>>, Vec<Event<'a>>),
@ -11,6 +14,7 @@ pub enum Event<'a> {
Trigger(Trigger<'a>),
}
#[derive(Clone)]
#[allow(dead_code)]
pub enum Trigger<'a> {
Goto(&'a str),
@ -26,18 +30,22 @@ pub enum Trigger<'a> {
Sleep(u64),
}
#[derive(Clone)]
pub enum Position {
Prev,
Next,
}
#[derive(Clone)]
pub enum Selector {
Title,
QueryParamStr,
}
#[derive(Clone)]
pub enum Assert<'a> {
Eq(Selector, &'a str),
Contains(Selector, &'a str),
ContainsAny(Selector, Vec<&'a str>),
IsPresent(&'a str),
IsPresentNow(&'a str),
}
@ -46,6 +54,15 @@ pub static CHEKOUT_BASE_URL: &str = "https://hs-payments-test.netlify.app";
pub static CHEKOUT_DOMAIN: &str = "hs-payments-test.netlify.app";
#[async_trait]
pub trait SeleniumTest {
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")
}
fn get_connector_name(&self) -> String;
async fn complete_actions(
&self,
driver: &WebDriver,
@ -61,6 +78,15 @@ pub trait SeleniumTest {
}
_ => assert!(driver.title().await?.contains(text)),
},
Assert::ContainsAny(selector, search_keys) => match selector {
Selector::QueryParamStr => {
let url = driver.current_url().await?;
assert!(search_keys
.iter()
.any(|key| url.query().unwrap().contains(key)))
}
_ => assert!(driver.title().await?.contains(search_keys.first().unwrap())),
},
Assert::Eq(_selector, text) => assert_eq!(driver.title().await?, text),
Assert::IsPresent(text) => {
assert!(is_text_present(driver, text).await?)
@ -79,6 +105,15 @@ pub trait SeleniumTest {
}
_ => assert!(driver.title().await?.contains(text)),
},
Assert::ContainsAny(selector, keys) => match selector {
Selector::QueryParamStr => {
let url = driver.current_url().await?;
if keys.iter().any(|key| url.query().unwrap().contains(key)) {
self.complete_actions(driver, events).await?;
}
}
_ => assert!(driver.title().await?.contains(keys.first().unwrap())),
},
Assert::Eq(_selector, text) => {
if text == driver.title().await? {
self.complete_actions(driver, events).await?;
@ -111,6 +146,21 @@ pub trait SeleniumTest {
}
_ => assert!(driver.title().await?.contains(text)),
},
Assert::ContainsAny(selector, keys) => match selector {
Selector::QueryParamStr => {
let url = driver.current_url().await?;
self.complete_actions(
driver,
if keys.iter().any(|key| url.query().unwrap().contains(key)) {
success
} else {
failure
},
)
.await?;
}
_ => assert!(driver.title().await?.contains(keys.first().unwrap())),
},
Assert::Eq(_selector, text) => {
self.complete_actions(
driver,
@ -148,16 +198,35 @@ pub trait SeleniumTest {
Event::Trigger(trigger) => match trigger {
Trigger::Goto(url) => {
driver.goto(url).await?;
let hs_base_url =
env::var("HS_BASE_URL").unwrap_or("http://localhost:8080".to_string()); //Issue: #924
let hs_api_key =
env::var("HS_API_KEY").expect("Hyperswitch user API key not present"); //Issue: #924
let conf = serde_json::to_string(&self.get_configs()).unwrap();
let hs_base_url = self
.get_configs()
.automation_configs
.unwrap()
.hs_base_url
.unwrap_or_else(|| "http://localhost:8080".to_string());
let configs_url = self
.get_configs()
.automation_configs
.unwrap()
.configs_url
.unwrap();
let script = &[
format!("localStorage.configs='{configs_url}'").as_str(),
format!("localStorage.hs_api_configs='{conf}'").as_str(),
"localStorage.force_sync='true'",
format!(
"localStorage.current_connector=\"{}\";",
self.get_connector_name().clone()
)
.as_str(),
]
.join(";");
driver.execute(script, Vec::new()).await?;
driver
.add_cookie(new_cookie("hs_base_url", hs_base_url).clone())
.await?;
driver
.add_cookie(new_cookie("hs_api_key", hs_api_key).clone())
.await?;
}
Trigger::Click(by) => {
let ele = driver.query(by).first().await?;
@ -232,18 +301,21 @@ pub trait SeleniumTest {
c: WebDriver,
actions: Vec<Event<'_>>,
) -> Result<(), WebDriverError> {
let config = self.get_configs().automation_configs.unwrap();
if config.run_minimum_steps.unwrap() {
self.complete_actions(&c, actions[..3].to_vec()).await
} else {
self.complete_actions(&c, actions).await
}
}
async fn make_gpay_payment(
&self,
c: WebDriver,
url: &str,
actions: Vec<Event<'_>>,
) -> Result<(), WebDriverError> {
let (email, pass) = (
&get_env("GMAIL_EMAIL").clone(),
&get_env("GMAIL_PASS").clone(),
);
let config = self.get_configs().automation_configs.unwrap();
let (email, pass) = (&config.gmail_email.unwrap(), &config.gmail_pass.unwrap());
let default_actions = vec![
Event::Trigger(Trigger::Goto(url)),
Event::Trigger(Trigger::Click(By::Css(".gpay-button"))),
@ -294,8 +366,18 @@ pub trait SeleniumTest {
)
.await?;
let (email, pass) = (
&get_env("PYPL_EMAIL").clone(),
&get_env("PYPL_PASS").clone(),
&self
.get_configs()
.automation_configs
.unwrap()
.pypl_email
.unwrap(),
&self
.get_configs()
.automation_configs
.unwrap()
.pypl_pass
.unwrap(),
);
let mut pypl_actions = vec![
Event::EitherOr(
@ -392,7 +474,7 @@ macro_rules! tester {
}
pub fn get_browser() -> String {
env::var("HS_TEST_BROWSER").unwrap_or("firefox".to_string()) //Issue: #924
"firefox".to_string()
}
pub fn make_capabilities(s: &str) -> Capabilities {
@ -420,9 +502,6 @@ pub fn make_capabilities(s: &str) -> Capabilities {
}
}
fn get_chrome_profile_path() -> Result<String, WebDriverError> {
env::var("CHROME_PROFILE_PATH").map_or_else(
//Issue: #924
|_| -> Result<String, WebDriverError> {
let exe = env::current_exe()?;
let dir = exe.parent().expect("Executable must be in some directory");
let mut base_path = dir
@ -435,14 +514,8 @@ fn get_chrome_profile_path() -> Result<String, WebDriverError> {
.unwrap();
base_path.push_str(r#"/Library/Application\ Support/Google/Chrome/Default"#);
Ok(base_path)
},
Ok,
)
}
fn get_firefox_profile_path() -> Result<String, WebDriverError> {
env::var("FIREFOX_PROFILE_PATH").map_or_else(
//Issue: #924
|_| -> Result<String, WebDriverError> {
let exe = env::current_exe()?;
let dir = exe.parent().expect("Executable must be in some directory");
let mut base_path = dir
@ -455,9 +528,6 @@ fn get_firefox_profile_path() -> Result<String, WebDriverError> {
.unwrap();
base_path.push_str(r#"/Library/Application Support/Firefox/Profiles/hs-test"#);
Ok(base_path)
},
Ok,
)
}
pub fn make_url(s: &str) -> &'static str {
@ -487,7 +557,3 @@ pub fn handle_test_error(
}
}
}
pub fn get_env(name: &str) -> String {
env::var(name).unwrap_or_else(|_| panic!("{name} not present")) //Issue: #924
}

View File

@ -5,7 +5,11 @@ use crate::{selenium::*, tester};
struct StripeSeleniumTest;
impl SeleniumTest for StripeSeleniumTest {}
impl SeleniumTest for StripeSeleniumTest {
fn get_connector_name(&self) -> String {
"stripe".to_string()
}
}
async fn should_make_3ds_payment(c: WebDriver) -> Result<(), WebDriverError> {
let conn = StripeSeleniumTest {};
@ -29,7 +33,7 @@ async fn should_make_3ds_mandate_payment(c: WebDriver) -> Result<(), WebDriverEr
Event::Assert(Assert::IsPresent("succeeded")),
Event::Assert(Assert::IsPresent("Mandate ID")),
Event::Assert(Assert::IsPresent("man_")),// mandate id starting with man_
Event::Trigger(Trigger::Click(By::Id("pm-mandate-btn"))),
Event::Trigger(Trigger::Click(By::Css("#pm-mandate-btn a"))),
Event::Trigger(Trigger::Click(By::Id("pay-with-mandate-btn"))),
Event::Assert(Assert::IsPresent("succeeded")),
@ -48,7 +52,7 @@ async fn should_fail_recurring_payment_due_to_authentication(
Event::Assert(Assert::IsPresent("succeeded")),
Event::Assert(Assert::IsPresent("Mandate ID")),
Event::Assert(Assert::IsPresent("man_")),// mandate id starting with man_
Event::Trigger(Trigger::Click(By::Id("pm-mandate-btn"))),
Event::Trigger(Trigger::Click(By::Css("#pm-mandate-btn a"))),
Event::Trigger(Trigger::Click(By::Id("pay-with-mandate-btn"))),
Event::Assert(Assert::IsPresent("authentication_required: Your card was declined. This transaction requires authentication.")),
@ -67,7 +71,7 @@ async fn should_make_3ds_mandate_with_zero_dollar_payment(
Event::Assert(Assert::IsPresent("succeeded")),
Event::Assert(Assert::IsPresent("Mandate ID")),
Event::Assert(Assert::IsPresent("man_")),// mandate id starting with man_
Event::Trigger(Trigger::Click(By::Id("pm-mandate-btn"))),
Event::Trigger(Trigger::Click(By::Css("#pm-mandate-btn a"))),
Event::Trigger(Trigger::Click(By::Id("pay-with-mandate-btn"))),
// Need to be handled as mentioned in https://stripe.com/docs/payments/save-and-reuse?platform=web#charge-saved-payment-method
Event::Assert(Assert::IsPresent("succeeded")),
@ -78,8 +82,14 @@ async fn should_make_3ds_mandate_with_zero_dollar_payment(
async fn should_make_gpay_payment(c: WebDriver) -> Result<(), WebDriverError> {
let conn = StripeSeleniumTest {};
let pub_key = conn
.get_configs()
.automation_configs
.unwrap()
.stripe_pub_key
.unwrap();
conn.make_gpay_payment(c,
&format!("{CHEKOUT_BASE_URL}/gpay?gatewayname=stripe&gpaycustomfields[stripe:version]=2018-10-31&gpaycustomfields[stripe:publishableKey]=pk_test_51Msk2GAGHc77EJXX78h549SX2uaOnEkUYqBfjcoD05PIpAnDkYxMn8nQ4d19im85NQuX4Z6WDyHaUw2fFTPBWsIY00Wa7oNerO&amount=70.00&country=US&currency=USD"),
&format!("{CHEKOUT_BASE_URL}/gpay?gatewayname=stripe&gpaycustomfields[stripe:version]=2018-10-31&gpaycustomfields[stripe:publishableKey]={pub_key}&amount=70.00&country=US&currency=USD"),
vec![
Event::Assert(Assert::IsPresent("succeeded")),
]).await?;
@ -88,20 +98,288 @@ async fn should_make_gpay_payment(c: WebDriver) -> Result<(), WebDriverError> {
async fn should_make_gpay_mandate_payment(c: WebDriver) -> Result<(), WebDriverError> {
let conn = StripeSeleniumTest {};
let pub_key = conn
.get_configs()
.automation_configs
.unwrap()
.stripe_pub_key
.unwrap();
conn.make_gpay_payment(c,
&format!("{CHEKOUT_BASE_URL}/gpay?gatewayname=stripe&gpaycustomfields[stripe:version]=2018-10-31&gpaycustomfields[stripe:publishableKey]=pk_test_51Msk2GAGHc77EJXX78h549SX2uaOnEkUYqBfjcoD05PIpAnDkYxMn8nQ4d19im85NQuX4Z6WDyHaUw2fFTPBWsIY00Wa7oNerO&amount=70.00&country=US&currency=USD&mandate_data[customer_acceptance][acceptance_type]=offline&mandate_data[customer_acceptance][accepted_at]=1963-05-03T04:07:52.723Z&mandate_data[customer_acceptance][online][ip_address]=127.0.0.1&mandate_data[customer_acceptance][online][user_agent]=amet%20irure%20esse&mandate_data[mandate_type][multi_use][amount]=700&mandate_data[mandate_type][multi_use][currency]=USD"),
&format!("{CHEKOUT_BASE_URL}/gpay?gatewayname=stripe&gpaycustomfields[stripe:version]=2018-10-31&gpaycustomfields[stripe:publishableKey]={pub_key}&amount=70.00&country=US&currency=USD&mandate_data[customer_acceptance][acceptance_type]=offline&mandate_data[customer_acceptance][accepted_at]=1963-05-03T04:07:52.723Z&mandate_data[customer_acceptance][online][ip_address]=127.0.0.1&mandate_data[customer_acceptance][online][user_agent]=amet%20irure%20esse&mandate_data[mandate_type][multi_use][amount]=700&mandate_data[mandate_type][multi_use][currency]=USD"),
vec![
Event::Assert(Assert::IsPresent("succeeded")),
Event::Assert(Assert::IsPresent("Mandate ID")),
Event::Assert(Assert::IsPresent("man_")),// mandate id starting with man_
Event::Trigger(Trigger::Click(By::Id("pm-mandate-btn"))),
Event::Trigger(Trigger::Click(By::Css("#pm-mandate-btn a"))),
Event::Trigger(Trigger::Click(By::Id("pay-with-mandate-btn"))),
Event::Assert(Assert::IsPresent("succeeded")),
]).await?;
Ok(())
}
#[ignore = "Different flows"]
//https://stripe.com/docs/testing#regulatory-cards
async fn should_make_stripe_klarna_payment(c: WebDriver) -> Result<(), WebDriverError> {
let conn = StripeSeleniumTest {};
conn.make_redirection_payment(
c,
vec![
Event::Trigger(Trigger::Goto(&format!("{CHEKOUT_BASE_URL}/saved/19"))),
Event::Trigger(Trigger::Click(By::Id("card-submit-btn"))),
Event::Trigger(Trigger::SwitchFrame(By::Id("klarna-apf-iframe"))),
Event::RunIf(
Assert::IsPresent("Lets verify your phone"),
vec![
Event::Trigger(Trigger::SendKeys(By::Id("phone"), "8056594427")),
Event::Trigger(Trigger::Click(By::Id("onContinue"))),
Event::Trigger(Trigger::SendKeys(By::Id("otp_field"), "123456")),
],
),
Event::RunIf(
Assert::IsPresent("Pick a plan"),
vec![Event::Trigger(Trigger::Click(By::Css(
"button[data-testid='pick-plan']",
)))],
),
Event::Trigger(Trigger::Click(By::Css(
"button[data-testid='confirm-and-pay']",
))),
Event::Trigger(Trigger::SwitchTab(Position::Prev)),
Event::Assert(Assert::IsPresent("Google")),
Event::Assert(Assert::Contains(
Selector::QueryParamStr,
"status=succeeded",
)),
],
)
.await?;
Ok(())
}
async fn should_make_afterpay_payment(c: WebDriver) -> Result<(), WebDriverError> {
let conn = StripeSeleniumTest {};
conn.make_redirection_payment(
c,
vec![
Event::Trigger(Trigger::Goto(&format!("{CHEKOUT_BASE_URL}/saved/22"))),
Event::Trigger(Trigger::Click(By::Id("card-submit-btn"))),
Event::Trigger(Trigger::Click(By::Css(
"a[class='common-Button common-Button--default']",
))),
Event::Assert(Assert::IsPresent("Google")),
Event::Assert(Assert::Contains(
Selector::QueryParamStr,
"status=succeeded",
)),
],
)
.await?;
Ok(())
}
async fn should_make_stripe_alipay_payment(c: WebDriver) -> Result<(), WebDriverError> {
let conn = StripeSeleniumTest {};
conn.make_redirection_payment(
c,
vec![
Event::Trigger(Trigger::Goto(&format!("{CHEKOUT_BASE_URL}/saved/35"))),
Event::Trigger(Trigger::Click(By::Id("card-submit-btn"))),
Event::Trigger(Trigger::Click(By::Css(
"button[class='common-Button common-Button--default']",
))),
Event::Trigger(Trigger::Sleep(5)),
Event::Assert(Assert::IsPresent("Google")),
Event::Assert(Assert::Contains(
Selector::QueryParamStr,
"status=succeeded",
)),
],
)
.await?;
Ok(())
}
async fn should_make_stripe_ideal_bank_redirect_payment(
c: WebDriver,
) -> Result<(), WebDriverError> {
let conn = StripeSeleniumTest {};
conn.make_redirection_payment(
c,
vec![
Event::Trigger(Trigger::Goto(&format!("{CHEKOUT_BASE_URL}/saved/2"))),
Event::Trigger(Trigger::Click(By::Id("card-submit-btn"))),
Event::Trigger(Trigger::Click(By::Css(
"a[class='common-Button common-Button--default']",
))),
Event::Assert(Assert::IsPresent("Google")),
Event::Assert(Assert::Contains(
Selector::QueryParamStr,
"status=succeeded",
)),
],
)
.await?;
Ok(())
}
async fn should_make_stripe_giropay_bank_redirect_payment(
c: WebDriver,
) -> Result<(), WebDriverError> {
let conn = StripeSeleniumTest {};
conn.make_redirection_payment(
c,
vec![
Event::Trigger(Trigger::Goto(&format!("{CHEKOUT_BASE_URL}/saved/1"))),
Event::Trigger(Trigger::Click(By::Id("card-submit-btn"))),
Event::Trigger(Trigger::Click(By::Css(
"a[class='common-Button common-Button--default']",
))),
Event::Assert(Assert::IsPresent("Google")),
Event::Assert(Assert::Contains(
Selector::QueryParamStr,
"status=succeeded",
)),
],
)
.await?;
Ok(())
}
async fn should_make_stripe_eps_bank_redirect_payment(c: WebDriver) -> Result<(), WebDriverError> {
let conn = StripeSeleniumTest {};
conn.make_redirection_payment(
c,
vec![
Event::Trigger(Trigger::Goto(&format!("{CHEKOUT_BASE_URL}/saved/26"))),
Event::Trigger(Trigger::Click(By::Id("card-submit-btn"))),
Event::Trigger(Trigger::Click(By::Css(
"a[class='common-Button common-Button--default']",
))),
Event::Assert(Assert::IsPresent("Google")),
Event::Assert(Assert::Contains(
Selector::QueryParamStr,
"status=succeeded",
)),
],
)
.await?;
Ok(())
}
async fn should_make_stripe_bancontact_card_redirect_payment(
c: WebDriver,
) -> Result<(), WebDriverError> {
let conn = StripeSeleniumTest {};
conn.make_redirection_payment(
c,
vec![
Event::Trigger(Trigger::Goto(&format!("{CHEKOUT_BASE_URL}/saved/28"))),
Event::Trigger(Trigger::Click(By::Id("card-submit-btn"))),
Event::Trigger(Trigger::Click(By::Css(
"a[class='common-Button common-Button--default']",
))),
Event::Assert(Assert::IsPresent("Google")),
Event::Assert(Assert::Contains(
Selector::QueryParamStr,
"status=succeeded",
)),
],
)
.await?;
Ok(())
}
async fn should_make_stripe_p24_redirect_payment(c: WebDriver) -> Result<(), WebDriverError> {
let conn = StripeSeleniumTest {};
conn.make_redirection_payment(
c,
vec![
Event::Trigger(Trigger::Goto(&format!("{CHEKOUT_BASE_URL}/saved/31"))),
Event::Trigger(Trigger::Click(By::Id("card-submit-btn"))),
Event::Trigger(Trigger::Click(By::Css(
"a[class='common-Button common-Button--default']",
))),
Event::Assert(Assert::IsPresent("Google")),
Event::Assert(Assert::Contains(
Selector::QueryParamStr,
"status=succeeded",
)),
],
)
.await?;
Ok(())
}
async fn should_make_stripe_sofort_redirect_payment(c: WebDriver) -> Result<(), WebDriverError> {
let conn = StripeSeleniumTest {};
conn.make_redirection_payment(
c,
vec![
Event::Trigger(Trigger::Goto(&format!("{CHEKOUT_BASE_URL}/saved/34"))),
Event::Trigger(Trigger::Click(By::Id("card-submit-btn"))),
Event::Trigger(Trigger::Click(By::Css(
"a[class='common-Button common-Button--default']",
))),
Event::Assert(Assert::IsPresent("Google")),
Event::Assert(Assert::ContainsAny(
Selector::QueryParamStr,
vec!["status=processing", "status=succeeded"],
)),
],
)
.await?;
Ok(())
}
async fn should_make_stripe_ach_bank_debit_payment(c: WebDriver) -> Result<(), WebDriverError> {
let conn = StripeSeleniumTest {};
conn.make_redirection_payment(
c,
vec![
Event::Trigger(Trigger::Goto(&format!("{CHEKOUT_BASE_URL}/saved/56"))),
Event::Trigger(Trigger::Click(By::Id("card-submit-btn"))),
Event::Trigger(Trigger::SendKeys(
By::Css("input[class='p-CodePuncher-controllingInput']"),
"11AA",
)),
Event::Trigger(Trigger::Click(By::Css(
"div[class='SubmitButton-IconContainer']",
))),
Event::Assert(Assert::IsPresent("Thanks for your payment")),
Event::Assert(Assert::IsPresent("You completed a payment")),
],
)
.await?;
Ok(())
}
async fn should_make_stripe_becs_bank_debit_payment(c: WebDriver) -> Result<(), WebDriverError> {
let conn = StripeSeleniumTest {};
conn.make_redirection_payment(
c,
vec![
Event::Trigger(Trigger::Goto(&format!("{CHEKOUT_BASE_URL}/saved/56"))),
Event::Trigger(Trigger::Click(By::Id("card-submit-btn"))),
Event::Assert(Assert::IsPresent("processing")),
],
)
.await?;
Ok(())
}
async fn should_make_stripe_sepa_bank_debit_payment(c: WebDriver) -> Result<(), WebDriverError> {
let conn = StripeSeleniumTest {};
conn.make_redirection_payment(
c,
vec![
Event::Trigger(Trigger::Goto(&format!("{CHEKOUT_BASE_URL}/saved/67"))),
Event::Trigger(Trigger::Click(By::Id("card-submit-btn"))),
Event::Assert(Assert::IsPresent("processing")),
],
)
.await?;
Ok(())
}
#[test]
#[serial]
@ -138,3 +416,75 @@ fn should_make_gpay_payment_test() {
fn should_make_gpay_mandate_payment_test() {
tester!(should_make_gpay_mandate_payment);
}
#[test]
#[serial]
fn should_make_stripe_klarna_payment_test() {
tester!(should_make_stripe_klarna_payment);
}
#[test]
#[serial]
fn should_make_afterpay_payment_test() {
tester!(should_make_afterpay_payment);
}
#[test]
#[serial]
fn should_make_stripe_alipay_payment_test() {
tester!(should_make_stripe_alipay_payment);
}
#[test]
#[serial]
fn should_make_stripe_ideal_bank_redirect_payment_test() {
tester!(should_make_stripe_ideal_bank_redirect_payment);
}
#[test]
#[serial]
fn should_make_stripe_giropay_bank_redirect_payment_test() {
tester!(should_make_stripe_giropay_bank_redirect_payment);
}
#[test]
#[serial]
fn should_make_stripe_eps_bank_redirect_payment_test() {
tester!(should_make_stripe_eps_bank_redirect_payment);
}
#[test]
#[serial]
fn should_make_stripe_bancontact_card_redirect_payment_test() {
tester!(should_make_stripe_bancontact_card_redirect_payment);
}
#[test]
#[serial]
fn should_make_stripe_p24_redirect_payment_test() {
tester!(should_make_stripe_p24_redirect_payment);
}
#[test]
#[serial]
fn should_make_stripe_sofort_redirect_payment_test() {
tester!(should_make_stripe_sofort_redirect_payment);
}
#[test]
#[serial]
fn should_make_stripe_ach_bank_debit_payment_test() {
tester!(should_make_stripe_ach_bank_debit_payment);
}
#[test]
#[serial]
fn should_make_stripe_becs_bank_debit_payment_test() {
tester!(should_make_stripe_becs_bank_debit_payment);
}
#[test]
#[serial]
fn should_make_stripe_sepa_bank_debit_payment_test() {
tester!(should_make_stripe_sepa_bank_debit_payment);
}

View File

@ -0,0 +1,83 @@
use serial_test::serial;
use thirtyfour::{prelude::*, WebDriver};
use crate::{selenium::*, tester};
struct WorldlineSeleniumTest;
impl SeleniumTest for WorldlineSeleniumTest {
fn get_connector_name(&self) -> String {
"worldline".to_string()
}
}
async fn should_make_card_non_3ds_payment(c: WebDriver) -> Result<(), WebDriverError> {
let conn = WorldlineSeleniumTest {};
conn.make_redirection_payment(
c,
vec![
Event::Trigger(Trigger::Goto(&format!("{CHEKOUT_BASE_URL}/saved/71"))),
Event::Trigger(Trigger::Click(By::Id("card-submit-btn"))),
Event::Assert(Assert::IsPresent("status")),
Event::Assert(Assert::IsPresent("processing")),
],
)
.await?;
Ok(())
}
async fn should_make_worldline_ideal_redirect_payment(c: WebDriver) -> Result<(), WebDriverError> {
let conn = WorldlineSeleniumTest {};
conn.make_redirection_payment(
c,
vec![
Event::Trigger(Trigger::Goto(&format!("{CHEKOUT_BASE_URL}/saved/49"))),
Event::Trigger(Trigger::Click(By::Id("card-submit-btn"))),
Event::Assert(Assert::IsPresent("Google")),
Event::Assert(Assert::ContainsAny(
Selector::QueryParamStr,
vec!["status=requires_customer_action", "status=succeeded"],
)),
],
)
.await?;
Ok(())
}
async fn should_make_worldline_giropay_redirect_payment(
c: WebDriver,
) -> Result<(), WebDriverError> {
let conn = WorldlineSeleniumTest {};
conn.make_redirection_payment(
c,
vec![
Event::Trigger(Trigger::Goto(&format!("{CHEKOUT_BASE_URL}/saved/48"))),
Event::Trigger(Trigger::Click(By::Id("card-submit-btn"))),
Event::Assert(Assert::IsPresent("Google")),
Event::Assert(Assert::ContainsAny(
Selector::QueryParamStr,
vec!["status=requires_customer_action", "status=succeeded"],
)),
],
)
.await?;
Ok(())
}
#[test]
#[serial]
fn should_make_worldline_giropay_redirect_payment_test() {
tester!(should_make_worldline_giropay_redirect_payment);
}
#[test]
#[serial]
fn should_make_worldline_ideal_redirect_payment_test() {
tester!(should_make_worldline_ideal_redirect_payment);
}
#[test]
#[serial]
fn should_make_card_non_3ds_payment_test() {
tester!(should_make_card_non_3ds_payment);
}