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:
Pa1NarK
2023-09-26 17:43:02 +05:30
committed by GitHub
parent 67a3e8f534
commit f47a5d423e
10 changed files with 136 additions and 69 deletions

View File

@ -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
View 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

Binary file not shown.

View File

@ -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

4
.gitignore vendored
View File

@ -261,3 +261,7 @@ result*
# node_modules
node_modules/
**/connector_auth.toml
**/sample_auth.toml
**/auth.toml

View File

@ -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);
}

View File

@ -63,7 +63,6 @@ fn should_make_3ds_payment_test() {
#[test]
#[serial]
#[ignore]
fn should_make_gpay_payment_test() {
tester!(should_make_gpay_payment);
}

View File

@ -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<String, WebDriverError> {
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<String, WebDriverError> {
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)
}

View File

@ -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);
}

10
scripts/decrypt_browser_data.sh Executable file
View 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