Skip to content

Commit

Permalink
test: add non regression tests for domain imports (#1497)
Browse files Browse the repository at this point in the history
* Add data-testid on RowCount component

* Write simple non regression test for domain import

* Fix regression in domain import form

* Set backend version and build in e2e tests script

Large diff due to formatting

* Add debug log for uploaded file path

* Tidy tests

* Add error handling for cd command

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* Add version and build to functional tests workflow

* Include schema version in dummy fixture

---------

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
  • Loading branch information
nas-tabchiche and coderabbitai[bot] authored Feb 13, 2025
1 parent ec36e1c commit 2592fe5
Show file tree
Hide file tree
Showing 8 changed files with 241 additions and 138 deletions.
4 changes: 4 additions & 0 deletions .github/workflows/functional-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ jobs:
echo [email protected] >> .env
echo EMAIL_HOST_PASSWORD=password >> .env
echo EMAIL_PORT=1025 >> .env
echo CISO_ASSISTANT_VERSION=v4.2.0 >> .env
echo CISO_ASSISTANT_BUILD=$(git rev-parse --short HEAD) >> .env
- name: Run migrations
working-directory: ${{ env.backend-directory }}
run: |
Expand Down Expand Up @@ -204,6 +206,8 @@ jobs:
echo [email protected] >> .env
echo EMAIL_HOST_PASSWORD=password >> .env
echo EMAIL_PORT=1025 >> .env
echo CISO_ASSISTANT_VERSION=v4.2.0 >> .env
echo CISO_ASSISTANT_BUILD=$(git rev-parse --short HEAD) >> .env
echo DJANGO_SETTINGS_MODULE=enterprise_core.settings >> .env
echo LICENSE_SEATS=999 >> .env
- name: Run migrations
Expand Down
Binary file modified backend/fixtures/dummy-domain.bak
Binary file not shown.
1 change: 0 additions & 1 deletion frontend/src/lib/components/Forms/ModelForm.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,6 @@
taintedMessage: m.taintedFormMessage(),
validationMethod: 'auto',
onUpdated: async ({ form }) => {
createModalCache.deleteCache(model.urlModel);
if (form.message?.redirect) {
goto(getSecureRedirect(form.message.redirect));
}
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/lib/components/ModelTable/RowCount.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
const rowCount = handler.getRowCount();
</script>

<aside class="text-sm">
<aside class="text-sm" data-testid="row-count">
{#if $rowCount.total > 0}
{m.rowCount({ start: $rowCount.start, end: $rowCount.end, total: $rowCount.total })}
{:else}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,15 +72,15 @@ export const actions: Actions = {
return defaultDeleteFormAction({ event, urlModel: event.params.model! });
},
importFolder: async (event) => {
const formData = Object.fromEntries(await event.request.formData());
const formData = await event.request.formData();
if (!formData) return fail(400, { error: 'No form data' });

const form = await superValidate(formData, zod(modelSchema('folders-import')));
if (!form.valid) {
return fail(400, withFiles({ form }));
}

const { file } = formData as { file: File };
const { file } = Object.fromEntries(formData) as { file: File };

const endpoint = `${BASE_API_URL}/folders/import/${form.data.load_missing_libraries ? '?load_missing_libraries=true' : ''}`;

Expand Down
268 changes: 134 additions & 134 deletions frontend/tests/e2e-tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,67 +13,65 @@ MAILER_WEB_SERVER_PORT=8073
MAILER_SMTP_SERVER_PORT=1073

for arg in "$@"; do
if [[ $arg == --port* ]]; then
if [[ "${arg#*=}" =~ ^[0-9]+$ ]]; then
BACKEND_PORT="${arg#*=}"
else
echo "Invalid format for --port argument. Please use --port=PORT"
exit 1
fi
elif [[ $arg == --mailer* ]]; then
MAILER_PORTS="${arg#*=}"
if [[ $MAILER_PORTS =~ ^[0-9]+/[0-9]+$ ]]; then
IFS='/' read -ra PORTS <<<"$MAILER_PORTS"
MAILER_SMTP_SERVER_PORT="${PORTS[0]}"
MAILER_WEB_SERVER_PORT="${PORTS[1]}"
SCRIPT_SHORT_ARGS+=("-m")
else
echo "Invalid format for --mailer argument. Please use --mailer=PORT/PORT"
exit 1
fi
elif [[ $arg == -q ]]; then
QUICK_MODE_ACTIVATED=1
elif [[ $arg == -v ]]; then
STORE_BACKEND_OUTPUT=1
elif [[ $arg == -k ]]; then
KEEP_DATABASE_SNAPSHOT=1
elif [[ $arg == --* ]]; then
SCRIPT_LONG_ARGS+=("$arg")
elif [[ $arg == -* ]]; then
SCRIPT_SHORT_ARGS+=("$arg")
elif [[ $arg != -* ]]; then
TEST_PATHS+=("$arg")
fi
if [[ $arg == --port* ]]; then
if [[ "${arg#*=}" =~ ^[0-9]+$ ]]; then
BACKEND_PORT="${arg#*=}"
else
echo "Invalid format for --port argument. Please use --port=PORT"
exit 1
fi
elif [[ $arg == --mailer* ]]; then
MAILER_PORTS="${arg#*=}"
if [[ $MAILER_PORTS =~ ^[0-9]+/[0-9]+$ ]]; then
IFS='/' read -ra PORTS <<<"$MAILER_PORTS"
MAILER_SMTP_SERVER_PORT="${PORTS[0]}"
MAILER_WEB_SERVER_PORT="${PORTS[1]}"
SCRIPT_SHORT_ARGS+=("-m")
else
echo "Invalid format for --mailer argument. Please use --mailer=PORT/PORT"
exit 1
fi
elif [[ $arg == -q ]]; then
QUICK_MODE_ACTIVATED=1
elif [[ $arg == -v ]]; then
STORE_BACKEND_OUTPUT=1
elif [[ $arg == -k ]]; then
KEEP_DATABASE_SNAPSHOT=1
elif [[ $arg == --* ]]; then
SCRIPT_LONG_ARGS+=("$arg")
elif [[ $arg == -* ]]; then
SCRIPT_SHORT_ARGS+=("$arg")
elif [[ $arg != -* ]]; then
TEST_PATHS+=("$arg")
fi
done

if [[ " ${SCRIPT_SHORT_ARGS[@]} " =~ " -h " ]] || [[ " ${SCRIPT_LONG_ARGS[@]} " =~ " --help " ]]; then
echo "Usage: e2e-tests.sh [options] [test_path]"
echo "Run the end-to-end tests for the CISO Assistant application."
echo "Options:"
echo " -q Quick mode: execute only the tests 1 time with no retries and only 1 project"
echo " -k Keep a saved snapshot of the initial database and use it to avoid executing useless migrations."
echo " If the initial database hasn't been created running the tests with this option will create it."
echo " Running the tests without this option will delete the saved initial database."
echo " --port=PORT Run the backend server on the specified port (default: $BACKEND_PORT)"
echo " -m, --mailer=PORT/PORT Use an existing mailer service on the optionally defined ports (default: $MAILER_SMTP_SERVER_PORT/$MAILER_WEB_SERVER_PORT)"



echo "Playwright options:"
echo " --browser=NAME Run the tests in the specified browser (chromium, firefox, webkit)"
echo " --global-timeout=MS Maximum time this test suite can run in milliseconds (default: unlimited)"
echo " --grep=SEARCH Only run tests matching this regular expression (default: \".*\")"
echo " --headed Run the tests in headful mode"
echo " -h Show this help message and exit"
echo " --list List all the tests"
echo " --project=NAME Run the tests in the specified project (chromium, firefox, webkit)"
echo " --repeat-each=COUNT Run the tests the specified number of times (default: 1)"
echo " --retries=COUNT Set the number of retries for the tests"
echo " --timeout=MS Set the timeout for the tests in milliseconds"
echo " -v Show the output of the backend server"
echo -e " --workers=COUNT Number of concurrent workers or percentage of logical CPU cores, use 1 to run in a single worker (default: 1)"
echo " Be aware that increasing the number of workers may reduce tests accuracy and stability"
exit 0
echo "Usage: e2e-tests.sh [options] [test_path]"
echo "Run the end-to-end tests for the CISO Assistant application."
echo "Options:"
echo " -q Quick mode: execute only the tests 1 time with no retries and only 1 project"
echo " -k Keep a saved snapshot of the initial database and use it to avoid executing useless migrations."
echo " If the initial database hasn't been created running the tests with this option will create it."
echo " Running the tests without this option will delete the saved initial database."
echo " --port=PORT Run the backend server on the specified port (default: $BACKEND_PORT)"
echo " -m, --mailer=PORT/PORT Use an existing mailer service on the optionally defined ports (default: $MAILER_SMTP_SERVER_PORT/$MAILER_WEB_SERVER_PORT)"

echo "Playwright options:"
echo " --browser=NAME Run the tests in the specified browser (chromium, firefox, webkit)"
echo " --global-timeout=MS Maximum time this test suite can run in milliseconds (default: unlimited)"
echo " --grep=SEARCH Only run tests matching this regular expression (default: \".*\")"
echo " --headed Run the tests in headful mode"
echo " -h Show this help message and exit"
echo " --list List all the tests"
echo " --project=NAME Run the tests in the specified project (chromium, firefox, webkit)"
echo " --repeat-each=COUNT Run the tests the specified number of times (default: 1)"
echo " --retries=COUNT Set the number of retries for the tests"
echo " --timeout=MS Set the timeout for the tests in milliseconds"
echo " -v Show the output of the backend server"
echo -e " --workers=COUNT Number of concurrent workers or percentage of logical CPU cores, use 1 to run in a single worker (default: 1)"
echo " Be aware that increasing the number of workers may reduce tests accuracy and stability"
exit 0
fi

if [[ "$(id -u "$(whoami)")" -eq 0 ]]; then
Expand All @@ -96,78 +94,78 @@ s.close()
# We use "not" because 0 is True and 1 is False in bash
exit(not port_already_in_used)
"; then
echo "The port $BACKEND_PORT is already in use!"
echo "You can either:"
echo "- Kill the process which is currently using this port."
echo "- Change the backend test server port using --port=NEW_PORT and try again."
exit 1
echo "The port $BACKEND_PORT is already in use!"
echo "You can either:"
echo "- Kill the process which is currently using this port."
echo "- Change the backend test server port using --port=NEW_PORT and try again."
exit 1
fi

for PORT in $MAILER_WEB_SERVER_PORT $MAILER_SMTP_SERVER_PORT; do
if python3 -c "import socket;exit(0 if 0 == socket.socket(socket.AF_INET, socket.SOCK_STREAM).connect_ex(('localhost',$PORT)) else 1)"; then
if [[ ! " ${SCRIPT_SHORT_ARGS[@]} " =~ " -m " ]]; then
echo "The port $PORT is already in use!"
echo "Please stop the running process using the port or change the mailer port and try again."
exit 1
fi
elif [[ " ${SCRIPT_SHORT_ARGS[@]} " =~ " -m " ]]; then
echo "No mailer service is running on port $PORT!"
echo "Please start a mailer service on port $PORT or change the mailer port using --mailer=PORT/PORT and try again."
echo "You can also use the isolated test mailer service by removing the -m option."
exit 1
fi
if python3 -c "import socket;exit(0 if 0 == socket.socket(socket.AF_INET, socket.SOCK_STREAM).connect_ex(('localhost',$PORT)) else 1)"; then
if [[ ! " ${SCRIPT_SHORT_ARGS[@]} " =~ " -m " ]]; then
echo "The port $PORT is already in use!"
echo "Please stop the running process using the port or change the mailer port and try again."
exit 1
fi
elif [[ " ${SCRIPT_SHORT_ARGS[@]} " =~ " -m " ]]; then
echo "No mailer service is running on port $PORT!"
echo "Please start a mailer service on port $PORT or change the mailer port using --mailer=PORT/PORT and try again."
echo "You can also use the isolated test mailer service by removing the -m option."
exit 1
fi
done

cleanup() {
echo -e "\nCleaning up..."
if [[ -n "$BACKEND_PID" ]]; then
kill $BACKEND_PID >/dev/null 2>&1
echo "| backend server stopped"
fi
if [[ -f "$DB_DIR/$DB_NAME" ]]; then
rm "$DB_DIR/$DB_NAME"
echo "| test database deleted"
fi
if [[ -z "$KEEP_DATABASE_SNAPSHOT" && -f "$DB_DIR/$DB_INIT_NAME" ]]; then
rm "$DB_DIR/$DB_INIT_NAME"
echo "| test initial database snapshot deleted"
fi
# This is dead code for now, we must delete this code if we abandon the .testhistory file usage
# if [[ -d "$APP_DIR/frontend/tests/utils/.testhistory" ]]; then
# rm -rf "$APP_DIR/frontend/tests/utils/.testhistory"
# echo "| test data history removed"
# fi
# This must be at the end of the cleanup as the sudo command can block the script
if [[ -n "$MAILER_PID" ]]; then
sudo docker stop $MAILER_PID &>/dev/null
sudo docker rm $MAILER_PID &>/dev/null
echo "| mailer service stopped"
fi
trap - SIGINT SIGTERM EXIT
echo "Cleanup done"
exit 0
echo -e "\nCleaning up..."
if [[ -n "$BACKEND_PID" ]]; then
kill $BACKEND_PID >/dev/null 2>&1
echo "| backend server stopped"
fi
if [[ -f "$DB_DIR/$DB_NAME" ]]; then
rm "$DB_DIR/$DB_NAME"
echo "| test database deleted"
fi
if [[ -z "$KEEP_DATABASE_SNAPSHOT" && -f "$DB_DIR/$DB_INIT_NAME" ]]; then
rm "$DB_DIR/$DB_INIT_NAME"
echo "| test initial database snapshot deleted"
fi
# This is dead code for now, we must delete this code if we abandon the .testhistory file usage
# if [[ -d "$APP_DIR/frontend/tests/utils/.testhistory" ]]; then
# rm -rf "$APP_DIR/frontend/tests/utils/.testhistory"
# echo "| test data history removed"
# fi
# This must be at the end of the cleanup as the sudo command can block the script
if [[ -n "$MAILER_PID" ]]; then
sudo docker stop $MAILER_PID &>/dev/null
sudo docker rm $MAILER_PID &>/dev/null
echo "| mailer service stopped"
fi
trap - SIGINT SIGTERM EXIT
echo "Cleanup done"
exit 0
}

finish() {
echo "Test successfully completed!"
cleanup
echo "Test successfully completed!"
cleanup
}

trap cleanup SIGINT SIGTERM
trap finish EXIT

if [[ ! " ${SCRIPT_SHORT_ARGS[@]} " =~ " -m " ]]; then
if command -v docker &>/dev/null; then
echo "Starting mailer service..."
MAILER_PID=$(sudo docker run -d -p $MAILER_SMTP_SERVER_PORT:1025 -p $MAILER_WEB_SERVER_PORT:8025 mailhog/mailhog)
echo "Mailer service started on ports $MAILER_SMTP_SERVER_PORT/$MAILER_WEB_SERVER_PORT (Container ID: ${MAILER_PID:0:6})"
else
echo "Docker is not installed!"
echo "Please install Docker to use the isolated test mailer service or use -m to tell the tests to use an existing one."
exit 1
fi
if command -v docker &>/dev/null; then
echo "Starting mailer service..."
MAILER_PID=$(sudo docker run -d -p $MAILER_SMTP_SERVER_PORT:1025 -p $MAILER_WEB_SERVER_PORT:8025 mailhog/mailhog)
echo "Mailer service started on ports $MAILER_SMTP_SERVER_PORT/$MAILER_WEB_SERVER_PORT (Container ID: ${MAILER_PID:0:6})"
else
echo "Docker is not installed!"
echo "Please install Docker to use the isolated test mailer service or use -m to tell the tests to use an existing one."
exit 1
fi
else
echo "Using an existing mailer service on ports $MAILER_SMTP_SERVER_PORT/$MAILER_WEB_SERVER_PORT"
echo "Using an existing mailer service on ports $MAILER_SMTP_SERVER_PORT/$MAILER_WEB_SERVER_PORT"
fi

echo "Starting backend server..."
Expand All @@ -183,26 +181,28 @@ export DEFAULT_FROM_EMAIL='[email protected]'
export EMAIL_HOST=localhost
export EMAIL_HOST_PASSWORD=pwd
export EMAIL_PORT=$MAILER_SMTP_SERVER_PORT
export CISO_ASSISTANT_VERSION=$(git describe --tags --always)
export CISO_ASSISTANT_BUILD=$(git rev-parse --short HEAD)

cd $APP_DIR/backend/
cd $APP_DIR/backend/ || exit 1
if [[ -z $KEEP_DATABASE_SNAPSHOT ]]; then
poetry run python3 manage.py makemigrations
poetry run python3 manage.py migrate
poetry run python3 manage.py makemigrations
poetry run python3 manage.py migrate
elif [[ ! -f "$DB_DIR/$DB_INIT_NAME" ]]; then
poetry run python3 manage.py makemigrations
poetry run python3 manage.py migrate
cp "$DB_DIR/$DB_NAME" "$DB_DIR/$DB_INIT_NAME"
poetry run python3 manage.py makemigrations
poetry run python3 manage.py migrate
cp "$DB_DIR/$DB_NAME" "$DB_DIR/$DB_INIT_NAME"
else
# Copying the initial database instead of applying the migrations saves a lot of time
cp "$DB_DIR/$DB_INIT_NAME" "$DB_DIR/$DB_NAME"
# Copying the initial database instead of applying the migrations saves a lot of time
cp "$DB_DIR/$DB_INIT_NAME" "$DB_DIR/$DB_NAME"
fi

poetry run python3 manage.py createsuperuser --noinput
if [[ -n "$STORE_BACKEND_OUTPUT" ]]; then
nohup poetry run python3 manage.py runserver $BACKEND_PORT >$APP_DIR/frontend/tests/utils/.testbackendoutput.out 2>&1 &
echo "You can view the backend server output at $APP_DIR/frontend/tests/utils/.testbackendoutput.out"
if [[ -n "$STORE_BACKEND_OUTPUT" ]]; then
nohup poetry run python3 manage.py runserver $BACKEND_PORT >$APP_DIR/frontend/tests/utils/.testbackendoutput.out 2>&1 &
echo "You can view the backend server output at $APP_DIR/frontend/tests/utils/.testbackendoutput.out"
else
nohup poetry run python3 manage.py runserver $BACKEND_PORT >/dev/null 2>&1 &
nohup poetry run python3 manage.py runserver $BACKEND_PORT >/dev/null 2>&1 &
fi
BACKEND_PID=$!
echo "Test backend server started on port $BACKEND_PORT (PID: $BACKEND_PID)"
Expand All @@ -215,27 +215,27 @@ export MAILER_WEB_SERVER_PORT=$MAILER_WEB_SERVER_PORT
cd $APP_DIR/frontend/

if ((${#TEST_PATHS[@]} == 0)); then
echo "| running every functional test"
echo "| running every functional test"
else
echo "| running tests: ${TEST_PATHS[@]}"
echo "| running tests: ${TEST_PATHS[@]}"
fi
if ((${#SCRIPT_LONG_ARGS[@]} == 0)); then
echo "| without args"
echo "| without args"
else
echo "| with args: ${SCRIPT_LONG_ARGS[@]}"
echo "| with args: ${SCRIPT_LONG_ARGS[@]}"
fi
echo "=========================================================================================="

FRONTEND_HASH_FILE="$APP_DIR/frontend/tests/.frontend_hash"
FRONTEND_HASH=$(find "$APP_DIR/frontend/src" -type f \( -name "*.ts" -o -name "*.svelte" \) -print0 | xargs -0 md5sum | md5sum)

if ! cmp <(cat "$FRONTEND_HASH_FILE") <(echo "$FRONTEND_HASH") &>/dev/null; then
pnpm run build # Required for the "pnpm run preview" command of playwright.config.ts
echo "$FRONTEND_HASH" > "$FRONTEND_HASH_FILE"
pnpm run build # Required for the "pnpm run preview" command of playwright.config.ts
echo "$FRONTEND_HASH" >"$FRONTEND_HASH_FILE"
fi

if [[ -n "$QUICK_MODE_ACTIVATED" ]]; then
pnpm playwright test ./tests/functional/"${TEST_PATHS[@]}" --project=chromium "${SCRIPT_LONG_ARGS[@]}" "${SCRIPT_SHORT_ARGS[@]}"
pnpm playwright test ./tests/functional/"${TEST_PATHS[@]}" --project=chromium "${SCRIPT_LONG_ARGS[@]}" "${SCRIPT_SHORT_ARGS[@]}"
else
pnpm playwright test ./tests/functional/"${TEST_PATHS[@]}" "${SCRIPT_LONG_ARGS[@]}" "${SCRIPT_SHORT_ARGS[@]}"
pnpm playwright test ./tests/functional/"${TEST_PATHS[@]}" "${SCRIPT_LONG_ARGS[@]}" "${SCRIPT_SHORT_ARGS[@]}"
fi
Loading

0 comments on commit 2592fe5

Please sign in to comment.