mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-27 03:13:56 +08:00
ci(ui_test): Refactor core of UI tests to use injected browser data (#2178)
Co-authored-by: Jagan <jaganelavarasan@gmail.com>
This commit is contained in:
42
.github/scripts/run_ui_tests.sh
vendored
42
.github/scripts/run_ui_tests.sh
vendored
@ -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
|
|
||||||
44
.github/scripts/start_ui_test_server.sh
vendored
Executable file
44
.github/scripts/start_ui_test_server.sh
vendored
Executable file
@ -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
|
||||||
BIN
.github/secrets/browser_data.tar.gz.gpg
vendored
Normal file
BIN
.github/secrets/browser_data.tar.gz.gpg
vendored
Normal file
Binary file not shown.
54
.github/workflows/connector-ui-sanity-tests.yml
vendored
54
.github/workflows/connector-ui-sanity-tests.yml
vendored
@ -2,7 +2,6 @@ name: Connector UI Sanity Tests
|
|||||||
|
|
||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
pull_request:
|
pull_request:
|
||||||
merge_group:
|
merge_group:
|
||||||
types:
|
types:
|
||||||
@ -34,6 +33,7 @@ env:
|
|||||||
RUST_BACKTRACE: short
|
RUST_BACKTRACE: short
|
||||||
# Use cargo's sparse index protocol
|
# Use cargo's sparse index protocol
|
||||||
CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse
|
CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse
|
||||||
|
RUST_MIN_STACK: 10485760
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
test_connectors:
|
test_connectors:
|
||||||
@ -42,7 +42,7 @@ jobs:
|
|||||||
|
|
||||||
services:
|
services:
|
||||||
redis:
|
redis:
|
||||||
image: redis
|
image: "redis"
|
||||||
options: >-
|
options: >-
|
||||||
--health-cmd "redis-cli ping"
|
--health-cmd "redis-cli ping"
|
||||||
--health-interval 10s
|
--health-interval 10s
|
||||||
@ -51,7 +51,7 @@ jobs:
|
|||||||
ports:
|
ports:
|
||||||
- 6379:6379
|
- 6379:6379
|
||||||
postgres:
|
postgres:
|
||||||
image: postgres:14.5
|
image: "postgres:14.5"
|
||||||
env:
|
env:
|
||||||
POSTGRES_USER: db_user
|
POSTGRES_USER: db_user
|
||||||
POSTGRES_PASSWORD: db_pass
|
POSTGRES_PASSWORD: db_pass
|
||||||
@ -71,7 +71,6 @@ jobs:
|
|||||||
# do not use more than 2 runners, try to group less time taking connectors together
|
# 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
|
- stripe,airwallex,bluesnap,checkout,trustpay_3ds,payu,authorizedotnet,aci,noon
|
||||||
- adyen_uk,shift4,worldline,multisafepay,paypal,mollie,nexinets
|
- adyen_uk,shift4,worldline,multisafepay,paypal,mollie,nexinets
|
||||||
|
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Ignore Tests incase of merge group or pull request from external repository
|
- name: Ignore Tests incase of merge group or pull request from external repository
|
||||||
@ -113,9 +112,11 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
toolchain: stable
|
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) }}
|
if: ${{ (github.event_name == 'pull_request') && (github.event.pull_request.head.repo.full_name == github.event.pull_request.base.repo.full_name) }}
|
||||||
with:
|
with:
|
||||||
crate: diesel_cli
|
crate: diesel_cli
|
||||||
@ -129,23 +130,38 @@ jobs:
|
|||||||
DATABASE_URL: postgres://db_user:db_pass@localhost:5432/hyperswitch_db
|
DATABASE_URL: postgres://db_user:db_pass@localhost:5432/hyperswitch_db
|
||||||
run: diesel migration run
|
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) }}
|
if: ${{ (github.event_name == 'pull_request') && (github.event.pull_request.head.repo.full_name == github.event.pull_request.base.repo.full_name) }}
|
||||||
env:
|
env:
|
||||||
|
BROWSER_DATA_PASSPHRASE: ${{ secrets.CONNECTOR_AUTH_PASSPHRASE }}
|
||||||
|
INPUT: ${{ matrix.connector }}
|
||||||
UI_TESTCASES_PATH: ${{ secrets.UI_TESTCASES_PATH }}
|
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 }}
|
INPUT: ${{ matrix.connector }}
|
||||||
shell: bash
|
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: |
|
run: |
|
||||||
if test "$( grep 'test result: FAILED' -r tests/test_results.log | wc -l )" -gt "0"; then
|
RED='\033[0;31m'
|
||||||
exit 1
|
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
|
fi
|
||||||
|
|||||||
4
.gitignore
vendored
4
.gitignore
vendored
@ -261,3 +261,7 @@ result*
|
|||||||
|
|
||||||
# node_modules
|
# node_modules
|
||||||
node_modules/
|
node_modules/
|
||||||
|
|
||||||
|
**/connector_auth.toml
|
||||||
|
**/sample_auth.toml
|
||||||
|
**/auth.toml
|
||||||
|
|||||||
@ -662,21 +662,18 @@ async fn should_make_adyen_momo_atm_payment(web_driver: WebDriver) -> Result<(),
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[serial]
|
#[serial]
|
||||||
#[ignore]
|
|
||||||
fn should_make_adyen_gpay_payment_test() {
|
fn should_make_adyen_gpay_payment_test() {
|
||||||
tester!(should_make_adyen_gpay_payment);
|
tester!(should_make_adyen_gpay_payment);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[serial]
|
#[serial]
|
||||||
#[ignore]
|
|
||||||
fn should_make_adyen_gpay_mandate_payment_test() {
|
fn should_make_adyen_gpay_mandate_payment_test() {
|
||||||
tester!(should_make_adyen_gpay_mandate_payment);
|
tester!(should_make_adyen_gpay_mandate_payment);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[serial]
|
#[serial]
|
||||||
#[ignore]
|
|
||||||
fn should_make_adyen_gpay_zero_dollar_mandate_payment_test() {
|
fn should_make_adyen_gpay_zero_dollar_mandate_payment_test() {
|
||||||
tester!(should_make_adyen_gpay_zero_dollar_mandate_payment);
|
tester!(should_make_adyen_gpay_zero_dollar_mandate_payment);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -63,7 +63,6 @@ fn should_make_3ds_payment_test() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[serial]
|
#[serial]
|
||||||
#[ignore]
|
|
||||||
fn should_make_gpay_payment_test() {
|
fn should_make_gpay_payment_test() {
|
||||||
tester!(should_make_gpay_payment);
|
tester!(should_make_gpay_payment);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -60,6 +60,7 @@ pub enum Assert<'a> {
|
|||||||
Eq(Selector, &'a str),
|
Eq(Selector, &'a str),
|
||||||
Contains(Selector, &'a str),
|
Contains(Selector, &'a str),
|
||||||
ContainsAny(Selector, Vec<&'a str>),
|
ContainsAny(Selector, Vec<&'a str>),
|
||||||
|
EitherOfThemExist(&'a str, &'a str),
|
||||||
IsPresent(&'a str),
|
IsPresent(&'a str),
|
||||||
IsElePresent(By),
|
IsElePresent(By),
|
||||||
IsPresentNow(&'a str),
|
IsPresentNow(&'a str),
|
||||||
@ -117,6 +118,10 @@ pub trait SeleniumTest {
|
|||||||
}
|
}
|
||||||
_ => assert!(driver.title().await?.contains(search_keys.first().unwrap())),
|
_ => 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::Eq(_selector, text) => assert_eq!(driver.title().await?, text),
|
||||||
Assert::IsPresent(text) => {
|
Assert::IsPresent(text) => {
|
||||||
assert!(is_text_present(driver, text).await?)
|
assert!(is_text_present(driver, text).await?)
|
||||||
@ -152,6 +157,13 @@ pub trait SeleniumTest {
|
|||||||
self.complete_actions(driver, events).await?;
|
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) => {
|
Assert::IsPresent(text) => {
|
||||||
if is_text_present(driver, text).await.is_ok() {
|
if is_text_present(driver, text).await.is_ok() {
|
||||||
self.complete_actions(driver, events).await?;
|
self.complete_actions(driver, events).await?;
|
||||||
@ -210,6 +222,19 @@ pub trait SeleniumTest {
|
|||||||
)
|
)
|
||||||
.await?;
|
.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) => {
|
Assert::IsPresent(text) => {
|
||||||
self.complete_actions(
|
self.complete_actions(
|
||||||
driver,
|
driver,
|
||||||
@ -400,7 +425,7 @@ pub trait SeleniumTest {
|
|||||||
Event::Trigger(Trigger::SwitchTab(Position::Next)),
|
Event::Trigger(Trigger::SwitchTab(Position::Next)),
|
||||||
Event::Trigger(Trigger::Sleep(5)),
|
Event::Trigger(Trigger::Sleep(5)),
|
||||||
Event::RunIf(
|
Event::RunIf(
|
||||||
Assert::IsPresentNow("Sign in"),
|
Assert::EitherOfThemExist("Use your Google Account", "Sign in"),
|
||||||
vec![
|
vec![
|
||||||
Event::Trigger(Trigger::SendKeys(By::Id("identifierId"), email)),
|
Event::Trigger(Trigger::SendKeys(By::Id("identifierId"), email)),
|
||||||
Event::Trigger(Trigger::ClickNth(By::Tag("button"), 2)),
|
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());
|
let profile_path = &format!("-profile={}", get_firefox_profile_path().unwrap());
|
||||||
caps.add_firefox_arg(profile_path).unwrap();
|
caps.add_firefox_arg(profile_path).unwrap();
|
||||||
} else {
|
} 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.add_firefox_arg("--headless").ok();
|
||||||
}
|
}
|
||||||
caps.into()
|
caps.into()
|
||||||
@ -832,7 +859,10 @@ fn get_chrome_profile_path() -> Result<String, WebDriverError> {
|
|||||||
fp.join(&MAIN_SEPARATOR.to_string())
|
fp.join(&MAIN_SEPARATOR.to_string())
|
||||||
})
|
})
|
||||||
.unwrap();
|
.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)
|
Ok(base_path)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -847,7 +877,17 @@ fn get_firefox_profile_path() -> Result<String, WebDriverError> {
|
|||||||
fp.join(&MAIN_SEPARATOR.to_string())
|
fp.join(&MAIN_SEPARATOR.to_string())
|
||||||
})
|
})
|
||||||
.unwrap();
|
.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)
|
Ok(base_path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -418,7 +418,6 @@ fn should_make_3ds_mandate_with_zero_dollar_payment_test() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[serial]
|
#[serial]
|
||||||
#[ignore]
|
|
||||||
fn should_make_gpay_payment_test() {
|
fn should_make_gpay_payment_test() {
|
||||||
tester!(should_make_gpay_payment);
|
tester!(should_make_gpay_payment);
|
||||||
}
|
}
|
||||||
|
|||||||
10
scripts/decrypt_browser_data.sh
Executable file
10
scripts/decrypt_browser_data.sh
Executable file
@ -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
|
||||||
Reference in New Issue
Block a user