diff --git a/.github/scripts/run_ui_tests.sh b/.github/scripts/run_ui_tests.sh deleted file mode 100644 index 5c7a0200dd..0000000000 --- a/.github/scripts/run_ui_tests.sh +++ /dev/null @@ -1,42 +0,0 @@ -#!/bin/bash -sudo apt update -apt install net-tools -mkdir tests - -COUNT=0 -#download connector ui tests -while [ ! -f $HOME/target/test/connector_tests.json ] -do - if [ $COUNT -gt 10 ]; - then - exit 1 - fi - COUNT=$((COUNT+1)) - sleep 2 - wget $UI_TESTCASES_PATH && mv testcases $HOME/target/test/connector_tests.json -done - -firefox --version -$GECKOWEBDRIVER/geckodriver > tests/geckodriver.log 2>&1 & - -#start server and run ui tests -cargo run & - -COUNT=0 -#Wait for the server to start in port 8080 -while netstat -lnt | awk '$4 ~ /:8080$/ {exit 1}'; do - #Wait for 15mins to start otherwise kill the task - if [ $COUNT -gt 90 ]; - then - exit 1 - else - COUNT=$((COUNT+1)) - sleep 10 - fi -done - -IN="$INPUT" -for i in $(echo $IN | tr "," "\n"); do - cargo test --package test_utils --test connectors -- "${i}_ui::" --test-threads=1 >> tests/test_results.log 2>&1 -done -cat tests/test_results.log \ No newline at end of file diff --git a/.github/scripts/start_ui_test_server.sh b/.github/scripts/start_ui_test_server.sh new file mode 100755 index 0000000000..619cc13d36 --- /dev/null +++ b/.github/scripts/start_ui_test_server.sh @@ -0,0 +1,44 @@ +#! /usr/bin/env bash + +sudo apt-get update +sudo apt-get install net-tools +mkdir tests + +COUNT=0 +# Download connector ui tests +while [ ! -f $HOME/target/test/connector_tests.json ] +do + if [ $COUNT -gt 10 ]; + then + exit 1 + fi + COUNT=$((COUNT+1)) + sleep 2 + wget $UI_TESTCASES_PATH && mv testcases $HOME/target/test/connector_tests.json +done + +curl --retry 10 --retry-delay 2 "${UI_TESTCASES_PATH}" --output "${HOME}/target/test/connector_tests.json" + +firefox --version +rm -rf $HOME/.mozilla + +sh ./scripts/decrypt_browser_data.sh "$BROWSER_DATA_PASSPHRASE" + +$GECKOWEBDRIVER/geckodriver > tests/geckodriver.log 2>&1 & + +# Start server and redirect logs to a file +target/debug/router & + +SERVER_PID=$! +# Wait for the server to start in port 8080 +COUNT=0 +while ! nc -z localhost 8080; do +if [ $COUNT -gt 12 ]; then # Wait for up to 2 minutes (12 * 10 seconds) + echo "Server did not start within a reasonable time. Exiting." + kill $SERVER_PID + exit 1 +else + COUNT=$((COUNT+1)) + sleep 10 +fi +done \ No newline at end of file diff --git a/.github/secrets/browser_data.tar.gz.gpg b/.github/secrets/browser_data.tar.gz.gpg new file mode 100644 index 0000000000..0b696077b1 Binary files /dev/null and b/.github/secrets/browser_data.tar.gz.gpg differ diff --git a/.github/workflows/connector-ui-sanity-tests.yml b/.github/workflows/connector-ui-sanity-tests.yml index 91c34638b7..5db45f2962 100644 --- a/.github/workflows/connector-ui-sanity-tests.yml +++ b/.github/workflows/connector-ui-sanity-tests.yml @@ -2,7 +2,6 @@ name: Connector UI Sanity Tests on: workflow_dispatch: - pull_request: merge_group: types: @@ -34,6 +33,7 @@ env: RUST_BACKTRACE: short # Use cargo's sparse index protocol CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse + RUST_MIN_STACK: 10485760 jobs: test_connectors: @@ -42,7 +42,7 @@ jobs: services: redis: - image: redis + image: "redis" options: >- --health-cmd "redis-cli ping" --health-interval 10s @@ -51,7 +51,7 @@ jobs: ports: - 6379:6379 postgres: - image: postgres:14.5 + image: "postgres:14.5" env: POSTGRES_USER: db_user POSTGRES_PASSWORD: db_pass @@ -71,7 +71,6 @@ jobs: # do not use more than 2 runners, try to group less time taking connectors together - stripe,airwallex,bluesnap,checkout,trustpay_3ds,payu,authorizedotnet,aci,noon - adyen_uk,shift4,worldline,multisafepay,paypal,mollie,nexinets - steps: - name: Ignore Tests incase of merge group or pull request from external repository @@ -113,9 +112,11 @@ jobs: with: toolchain: stable - - uses: Swatinem/rust-cache@v2.4.0 + - name: Build and Cache Rust Dependencies + uses: Swatinem/rust-cache@v2.4.0 - - uses: baptiste0928/cargo-install@v2.1.0 + - name: Install Diesel CLI with Postgres Support + uses: baptiste0928/cargo-install@v2.1.0 if: ${{ (github.event_name == 'pull_request') && (github.event.pull_request.head.repo.full_name == github.event.pull_request.base.repo.full_name) }} with: crate: diesel_cli @@ -129,23 +130,38 @@ jobs: DATABASE_URL: postgres://db_user:db_pass@localhost:5432/hyperswitch_db run: diesel migration run - - name: Start server and run tests + - name: Build project + if: ${{ (github.event_name == 'pull_request') && (github.event.pull_request.head.repo.full_name == github.event.pull_request.base.repo.full_name) }} + run: cargo build --package router --bin router + + - name: Start server if: ${{ (github.event_name == 'pull_request') && (github.event.pull_request.head.repo.full_name == github.event.pull_request.base.repo.full_name) }} env: + BROWSER_DATA_PASSPHRASE: ${{ secrets.CONNECTOR_AUTH_PASSPHRASE }} + INPUT: ${{ matrix.connector }} UI_TESTCASES_PATH: ${{ secrets.UI_TESTCASES_PATH }} + shell: bash + run: .github/scripts/start_ui_test_server.sh + + - name: Run tests + if: ${{ (github.event_name == 'pull_request') && (github.event.pull_request.head.repo.full_name == github.event.pull_request.base.repo.full_name) }} + env: INPUT: ${{ matrix.connector }} shell: bash - run: sh .github/scripts/run_ui_tests.sh - - - name: View test results - if: ${{ (github.event_name == 'pull_request') && (github.event.pull_request.head.repo.full_name == github.event.pull_request.base.repo.full_name) }} - shell: bash - run: cat tests/test_results.log - - - name: Check test results - if: ${{ (github.event_name == 'pull_request') && (github.event.pull_request.head.repo.full_name == github.event.pull_request.base.repo.full_name) }} - shell: bash run: | - if test "$( grep 'test result: FAILED' -r tests/test_results.log | wc -l )" -gt "0"; then - exit 1 + RED='\033[0;31m' + RESET='\033[0m' + failed_connectors=() + + for i in $(echo "$INPUT" | tr "," "\n"); do + echo $i + if ! cargo test --package test_utils --test connectors -- "${i}_ui::" --test-threads=1; then + failed_connectors+=("$i") + fi + done + + if [ ${#failed_connectors[@]} -gt 0 ]; then + echo -e "${RED}One or more connectors failed to run:${RESET}" + printf '%s\n' "${failed_connectors[@]}" + exit 1 fi diff --git a/.gitignore b/.gitignore index 81ef10ad21..62804a712f 100644 --- a/.gitignore +++ b/.gitignore @@ -261,3 +261,7 @@ result* # node_modules node_modules/ + +**/connector_auth.toml +**/sample_auth.toml +**/auth.toml diff --git a/crates/test_utils/tests/connectors/adyen_uk_ui.rs b/crates/test_utils/tests/connectors/adyen_uk_ui.rs index ee0d2f425b..bf42d01060 100644 --- a/crates/test_utils/tests/connectors/adyen_uk_ui.rs +++ b/crates/test_utils/tests/connectors/adyen_uk_ui.rs @@ -662,21 +662,18 @@ async fn should_make_adyen_momo_atm_payment(web_driver: WebDriver) -> Result<(), #[test] #[serial] -#[ignore] fn should_make_adyen_gpay_payment_test() { tester!(should_make_adyen_gpay_payment); } #[test] #[serial] -#[ignore] fn should_make_adyen_gpay_mandate_payment_test() { tester!(should_make_adyen_gpay_mandate_payment); } #[test] #[serial] -#[ignore] fn should_make_adyen_gpay_zero_dollar_mandate_payment_test() { tester!(should_make_adyen_gpay_zero_dollar_mandate_payment); } diff --git a/crates/test_utils/tests/connectors/bluesnap_ui.rs b/crates/test_utils/tests/connectors/bluesnap_ui.rs index ae1773ad1b..edc024f385 100644 --- a/crates/test_utils/tests/connectors/bluesnap_ui.rs +++ b/crates/test_utils/tests/connectors/bluesnap_ui.rs @@ -63,7 +63,6 @@ fn should_make_3ds_payment_test() { #[test] #[serial] -#[ignore] fn should_make_gpay_payment_test() { tester!(should_make_gpay_payment); } diff --git a/crates/test_utils/tests/connectors/selenium.rs b/crates/test_utils/tests/connectors/selenium.rs index 28cb5bad0e..865cd950f7 100644 --- a/crates/test_utils/tests/connectors/selenium.rs +++ b/crates/test_utils/tests/connectors/selenium.rs @@ -60,6 +60,7 @@ pub enum Assert<'a> { Eq(Selector, &'a str), Contains(Selector, &'a str), ContainsAny(Selector, Vec<&'a str>), + EitherOfThemExist(&'a str, &'a str), IsPresent(&'a str), IsElePresent(By), IsPresentNow(&'a str), @@ -117,6 +118,10 @@ pub trait SeleniumTest { } _ => assert!(driver.title().await?.contains(search_keys.first().unwrap())), }, + Assert::EitherOfThemExist(text_1, text_2) => assert!( + is_text_present_now(driver, text_1).await? + || is_text_present_now(driver, text_2).await? + ), Assert::Eq(_selector, text) => assert_eq!(driver.title().await?, text), Assert::IsPresent(text) => { assert!(is_text_present(driver, text).await?) @@ -152,6 +157,13 @@ pub trait SeleniumTest { self.complete_actions(driver, events).await?; } } + Assert::EitherOfThemExist(text_1, text_2) => { + if is_text_present_now(driver, text_1).await.is_ok() + || is_text_present_now(driver, text_2).await.is_ok() + { + self.complete_actions(driver, events).await?; + } + } Assert::IsPresent(text) => { if is_text_present(driver, text).await.is_ok() { self.complete_actions(driver, events).await?; @@ -210,6 +222,19 @@ pub trait SeleniumTest { ) .await?; } + Assert::EitherOfThemExist(text_1, text_2) => { + self.complete_actions( + driver, + if is_text_present_now(driver, text_1).await.is_ok() + || is_text_present_now(driver, text_2).await.is_ok() + { + success + } else { + failure + }, + ) + .await?; + } Assert::IsPresent(text) => { self.complete_actions( driver, @@ -400,7 +425,7 @@ pub trait SeleniumTest { Event::Trigger(Trigger::SwitchTab(Position::Next)), Event::Trigger(Trigger::Sleep(5)), Event::RunIf( - Assert::IsPresentNow("Sign in"), + Assert::EitherOfThemExist("Use your Google Account", "Sign in"), vec![ Event::Trigger(Trigger::SendKeys(By::Id("identifierId"), email)), Event::Trigger(Trigger::ClickNth(By::Tag("button"), 2)), @@ -807,6 +832,8 @@ pub fn make_capabilities(browser: &str) -> Capabilities { let profile_path = &format!("-profile={}", get_firefox_profile_path().unwrap()); caps.add_firefox_arg(profile_path).unwrap(); } else { + let profile_path = &format!("-profile={}", get_firefox_profile_path().unwrap()); + caps.add_firefox_arg(profile_path).unwrap(); caps.add_firefox_arg("--headless").ok(); } caps.into() @@ -832,7 +859,10 @@ fn get_chrome_profile_path() -> Result { fp.join(&MAIN_SEPARATOR.to_string()) }) .unwrap(); - base_path.push_str(r"/Library/Application\ Support/Google/Chrome/Default"); //Issue: 1573 + if env::consts::OS == "macos" { + base_path.push_str(r"/Library/Application\ Support/Google/Chrome/Default"); + //Issue: 1573 + } // We're only using Firefox on Ubuntu runner Ok(base_path) } @@ -847,7 +877,17 @@ fn get_firefox_profile_path() -> Result { fp.join(&MAIN_SEPARATOR.to_string()) }) .unwrap(); - base_path.push_str(r#"/Library/Application Support/Firefox/Profiles/hs-test"#); //Issue: 1573 + if env::consts::OS == "macos" { + base_path.push_str(r#"/Library/Application Support/Firefox/Profiles/hs-test"#); + //Issue: 1573 + } else if env::consts::OS == "linux" { + if let Some(home_dir) = env::var_os("HOME") { + if let Some(home_path) = home_dir.to_str() { + let profile_path = format!("{}/.mozilla/firefox/hs-test", home_path); + return Ok(profile_path); + } + } + } Ok(base_path) } diff --git a/crates/test_utils/tests/connectors/stripe_ui.rs b/crates/test_utils/tests/connectors/stripe_ui.rs index e69d134ce2..c2bf2bc9ce 100644 --- a/crates/test_utils/tests/connectors/stripe_ui.rs +++ b/crates/test_utils/tests/connectors/stripe_ui.rs @@ -418,7 +418,6 @@ fn should_make_3ds_mandate_with_zero_dollar_payment_test() { #[test] #[serial] -#[ignore] fn should_make_gpay_payment_test() { tester!(should_make_gpay_payment); } diff --git a/scripts/decrypt_browser_data.sh b/scripts/decrypt_browser_data.sh new file mode 100755 index 0000000000..7f1c79ad21 --- /dev/null +++ b/scripts/decrypt_browser_data.sh @@ -0,0 +1,10 @@ +#! /usr/bin/env bash + +# Decrypt the file +# --batch to prevent interactive command +# --yes to assume "yes" for questions +gpg --quiet --batch --yes --decrypt --passphrase="$1" \ +--output $HOME/browser_data.tar.gz .github/secrets/browser_data.tar.gz.gpg + +# Unzip the tarball +tar xzf $HOME/browser_data.tar.gz -C $HOME