diff --git a/scripts/ci/desktop-linux/smoke-test.sh b/scripts/ci/desktop-linux/smoke-test.sh index 25bed67bee..3c7e2dc0b4 100755 --- a/scripts/ci/desktop-linux/smoke-test.sh +++ b/scripts/ci/desktop-linux/smoke-test.sh @@ -1,12 +1,14 @@ #!/bin/bash # Starts the desktop app on a virtual display and runs the scripted UI cases with the ui helper: -# onboarding to the chat list, and a search of the test directory (backend.sh) from the chat list search field, -# with the toolbar at the bottom (the default) and then at the top. -# Usage: scripts/ci/desktop-linux/smoke-test.sh [onboarding] +# onboarding to the chat list; setup, which creates a local group and makes the test SMP server (backend.sh) the one +# that resolves SimpleX names; then, with the toolbar at the bottom (the default) and then at the top, a search of +# the test directory with "Search in Directory" and the full search with Enter, which also resolves a SimpleX name. +# Usage: scripts/ci/desktop-linux/smoke-test.sh [onboarding|setup] # With "onboarding" it stops at the chat list: releases before directory search show no search field without chats. +# With "setup" it stops after the setup. Setup needs NAMES_SERVER, the test SMP server's address. # Each step saves a numbered screenshot and the text read from it to the output dir, prints the text to the log, -# and adds a line to steps.log there. What the search shows is checked without stopping: every check is listed in +# and adds a line to steps.log there. What the searches show is checked without stopping: every check is listed in # checks.txt and the job summary, and the test fails at the end if any failed. The app keeps running for later # steps of the job, which get UI_OUT. @@ -16,10 +18,14 @@ app_dir=$1 export UI_OUT=$2 cases=${3:-all} search_text="ci seed" +# a SimpleX name candidate: Enter resolves seeded.testing, which backend.sh registered for ci_contact, +# and searches the directory, whose entries are "CI seeded ..." +name_text=seeded +local_chat="seeded notes" ui=$(dirname "$0")/ui checks=$UI_OUT/checks.txt -# the "Reachable app toolbars" switch, at the right of the left pane, where Settings open -toolbar_switch_x=335 +# switches are at the right of the left pane, where Settings open +switch_x=335 mkdir -p "$UI_OUT" : > "$checks" if [ -n "${GITHUB_ENV:-}" ]; then @@ -83,6 +89,12 @@ y_of() { cut -d ' ' -f 2 <<< "$pos" } +height_of() { + local x y l t r b + read -r x y l t r b < <("$ui" find "$1") || return 1 + echo $((b - t)) +} + above() { local a b a=$(y_of "$1") || return 1 @@ -90,6 +102,16 @@ above() { [ "$a" -lt "$b" ] } +# each text is above the next +in_order() { + local text y previous=-1 + for text in "$@"; do + y=$(y_of "$text") || return 1 + [ "$y" -gt "$previous" ] || return 1 + previous=$y + done +} + # the label is in the row headed by the name: below the name, by less than a row's height in_row_of() { local label name @@ -98,20 +120,27 @@ in_row_of() { [ "$label" -ge "$name" ] && [ $((label - name)) -lt 45 ] } -# Searches the directory for the text in the search field, and shows more results until both seeded ones are there: -# their avatars make each response hold one of them. -search_directory() { - local layout=$1 consent=$2 pages=1 retries=0 missing - "$ui" click-text "Search in Directory" - "$ui" wait "Search and don't show again" 10 - "$ui" shot "$layout-search-consent" - "$ui" click-text "$consent" +# the count's text is smaller than the description's above it: both have capitals and ascenders, no descenders +count_text_smaller() { + local count description + count=$(height_of "1 subscriber") || return 1 + description=$(height_of "CI seeded channel") || return 1 + echo "NOTE text heights: \"1 subscriber\" $count px, \"CI seeded channel\" $description px" | tee -a "$checks" + [ "$count" -lt "$description" ] +} + +# Shows more results until both seeded entries are listed: their avatars make each response hold one of them. +# Sets pages and retries. +show_all_results() { + local layout=$1 missing + pages=1 + retries=0 while :; do "$ui" wait "Join" 60 || true missing="" on_screen "#ci_channel" || missing="#ci_channel" on_screen "#ci_group" || missing="#ci_group" - "$ui" shot "$layout-directory-page-$pages" + "$ui" shot "$layout-page-$pages" [ -n "$missing" ] || break if on_screen "Search failed, tap to retry"; then retries=$((retries + 1)) @@ -125,45 +154,163 @@ search_directory() { fi done echo "NOTE $layout: the results came in $pages pages, after $retries retries" | tee -a "$checks" +} + +check_directory_rows() { + local layout=$1 check "$layout: the first page held one result, \"Show more\" loaded the other" [ "$pages" -eq 2 ] check "$layout: no more results offered" not_on_screen "Show more" check "$layout: \"Directory\" header above #ci_group" above "Directory" "#ci_group" check "$layout: \"Directory\" header above #ci_channel" above "Directory" "#ci_channel" check "$layout: #ci_group shows its red avatar" "$ui" avatar "#ci_group" red check "$layout: #ci_channel shows its green avatar" "$ui" avatar "#ci_channel" green - check "$layout: #ci_group row has \"CI seed group\"" in_row_of "CI seed group" "#ci_group" - check "$layout: #ci_channel row has \"CI seed channel\"" in_row_of "CI seed channel" "#ci_channel" + check "$layout: #ci_group row has \"CI seeded group\"" in_row_of "CI seeded group" "#ci_group" + check "$layout: #ci_channel row has \"CI seeded channel\"" in_row_of "CI seeded channel" "#ci_channel" check "$layout: #ci_group row has \"Join group\"" in_row_of "Join group" "#ci_group" check "$layout: #ci_channel row has \"Join channel\"" in_row_of "Join channel" "#ci_channel" - check "$layout: member count shown" on_screen "members" - check "$layout: subscriber count shown" on_screen "subscriber" + check "$layout: member count shown" on_screen "2 members" + check "$layout: subscriber count shown" on_screen "1 subscriber" +} + +# Searches the directory for the text in the search field with the "Search in Directory" row. +search_directory() { + local layout=$1 consent=$2 + "$ui" click-text "Search in Directory" + "$ui" wait "Search and don't show again" 10 + "$ui" shot "$layout-search-consent" + "$ui" click-text "$consent" + show_all_results "$layout-directory" + check_directory_rows "$layout" + check "$layout: the count's text is smaller than the description's" count_text_smaller +} + +# Types a SimpleX name and presses Enter, the desktop's Search key: the local chat that matches, then the Names part +# with the name's contact, then the Directory part, in the list's order outward from the search field. +full_search() { + local layout=$1 consent=$2 + "$ui" click-text "Search or paste SimpleX link" + "$ui" type "$name_text" + "$ui" wait "Connect to $name_text.testing" 15 + "$ui" shot "$layout-name-typed" + "$ui" key Return + if [ -n "$consent" ]; then + "$ui" wait "Search and don't show again" 10 + "$ui" click-text "$consent" + fi + "$ui" wait "ci_contact" 60 || true + show_all_results "$layout-full" + check_directory_rows "$layout full search" + check "$layout full search: \"$local_chat\" listed" on_screen "$local_chat" + check "$layout full search: \"Names\" header shown" on_screen "Names" + check "$layout full search: ci_contact found by its name" in_row_of "@$name_text.testing" "ci_contact" + check "$layout full search: ci_contact row has \"CI seeded contact\"" in_row_of "CI seeded contact" "ci_contact" + check "$layout full search: ci_contact shows its blue avatar" "$ui" avatar "ci_contact" blue + check "$layout full search: \"Connect to $name_text.testing\" gone once the name is found" not_on_screen "Connect to $name_text.testing" + check "$layout full search: \"Names\" header above ci_contact" above "Names" "ci_contact" + if [ "$layout" = top ]; then + check "$layout full search: local chat, Names, Directory, from the search field down" \ + in_order "Search in Directory" "$local_chat" "Names" "ci_contact" "Directory" "#ci_channel" + else + check "$layout full search: local chat, Names, Directory, from the search field up" \ + in_order "Directory" "#ci_channel" "Names" "ci_contact" "$local_chat" "Search in Directory" + fi +} + +# Escape closes one screen at a time, and clears the search field +back_to_chat_list() { + for _ in 1 2 3 4 5 6; do + if not_on_screen "Settings" && not_on_screen "Chat preferences" && not_on_screen "Network & servers" && on_screen "Search or paste SimpleX link"; then + return 0 + fi + "$ui" key Escape + done + on_screen "Search or paste SimpleX link" +} + +# Opens Settings from the user menu, behind the profile picture at the left of the bottom toolbar. +open_settings() { + "$ui" click 27 730 + "$ui" click-text "Settings" 10 } # Turns "Reachable app toolbars" off in Settings > Appearance, which moves the toolbar and the search field to the top. use_top_toolbar() { local y - # Escape clears the search field, and then closes one screen at a time "$ui" key Escape - # the profile picture at the left of the bottom toolbar opens the user menu - "$ui" click 27 730 - "$ui" click-text "Settings" 10 + open_settings "$ui" click-text "Appearance" 10 "$ui" wait "Reachable app toolbars" 10 "$ui" shot appearance y=$(y_of "Reachable app toolbars") - "$ui" click "$toolbar_switch_x" "$y" + "$ui" click "$switch_x" "$y" "$ui" shot appearance-toolbar-switched - for _ in 1 2 3 4 5; do - if not_on_screen "Appearance" && not_on_screen "Chat preferences" && on_screen "Search or paste SimpleX link"; then - break - fi - "$ui" key Escape - done + back_to_chat_list || true "$ui" shot top-chat-list y=$(y_of "Search or paste SimpleX link") || fail "no search field after closing Settings" [ "$y" -lt 200 ] || fail "the search field is still at the bottom (y $y) after switching Reachable app toolbars" } +# A group of the user's own, so the chat list has a chat that the full search matches and the directory doesn't list. +create_local_chat() { + local y + # the pencil at the right of the bottom toolbar opens New chat + "$ui" click 363 730 + "$ui" click-text "Create group" 10 + "$ui" wait "Enter group name" 10 + y=$(y_of "Enter group name") + "$ui" click 195 $((y + 40)) + "$ui" type "$local_chat" + "$ui" shot new-group + "$ui" click-text "Create group" 10 + "$ui" click-text "Skip inviting members" 20 || true + "$ui" shot group-created + "$ui" key Escape + "$ui" key Escape + back_to_chat_list || fail "no chat list after creating the group" + "$ui" wait "$local_chat" 10 || fail "\"$local_chat\" is not in the chat list" + "$ui" shot local-chat +} + +# Settings > Network & servers: the test SMP server added with the names role, and names off for the preset +# operators, so that only the test server resolves names. +use_names_server() { + local y operator + open_settings + "$ui" click-text "Network & servers" 10 + "$ui" click-text "Your servers" 10 + "$ui" click-text "Add server" 10 + "$ui" click-text "Enter server manually" 10 + "$ui" wait "Your server address" 10 + y=$(y_of "Your server address") + "$ui" click 195 $((y + 50)) + "$ui" type "$NAMES_SERVER" + y=$(y_of "Use for new connections") + "$ui" click "$switch_x" "$y" + "$ui" shot new-server + "$ui" key Escape + "$ui" click-text "127.0.0.1" 10 + "$ui" wait "To resolve names" 10 + "$ui" click-text "To resolve names" + "$ui" click-text "yes" 10 + "$ui" shot names-server-roles + "$ui" wait "To resolve names" 10 + in_row_of "yes" "To resolve names" || fail "the test server's \"To resolve names\" is not yes" + "$ui" key Escape + "$ui" key Escape + for operator in "SimpleX Chat" Flux; do + "$ui" click-text "$operator" 10 + "$ui" wait "To resolve names" 10 + y=$(y_of "To resolve names") + "$ui" click "$switch_x" "$y" + "$ui" shot "names-off-$(tr -cd 'a-zA-Z' <<< "$operator")" + "$ui" key Escape + done + "$ui" click-text "Save servers" 10 + sleep 2 + "$ui" shot servers-saved + back_to_chat_list || fail "no chat list after saving the servers" +} + "$ui" start "$app_dir" # onboarding to the chat list @@ -201,6 +348,14 @@ if [ "$cases" = onboarding ]; then exit 0 fi +: "${NAMES_SERVER:?NAMES_SERVER must be the test SMP server address}" +create_local_chat +use_names_server +if [ "$cases" = setup ]; then + echo "smoke test setup done: \"$local_chat\" created, $NAMES_SERVER resolves names" + exit 0 +fi + # typed text that is not a SimpleX link offers the directory; the default layout has the toolbar and the search field at the bottom "$ui" click-text "Search or paste SimpleX link" "$ui" type "$search_text" @@ -208,8 +363,10 @@ fi "$ui" wait "Search in Directory" 15 "$ui" shot bottom-search-typed search_directory bottom "Search" +"$ui" key Escape +full_search bottom "Search" -# the alert was answered with "Search", so it asks again +# the alert was answered with "Search" both times, so it asks again use_top_toolbar "$ui" click-text "Search or paste SimpleX link" "$ui" type "$search_text" @@ -217,8 +374,10 @@ use_top_toolbar "$ui" wait "Search in Directory" 15 "$ui" shot top-search-typed search_directory top "Search and don't show again" +"$ui" key Escape +full_search top "" if grep -q '^FAIL' "$checks"; then - fail "the search for \"$search_text\" failed checks: $(grep -c '^FAIL' "$checks") of $(grep -cE '^(PASS|FAIL)' "$checks")" + fail "the searches failed checks: $(grep -c '^FAIL' "$checks") of $(grep -cE '^(PASS|FAIL)' "$checks")" fi -echo "smoke test passed: the directory search for \"$search_text\" shows #ci_group and #ci_channel with their avatars, with the toolbar at the bottom and at the top" +echo "smoke test passed: \"Search in Directory\" for \"$search_text\" and the full search for \"$name_text\" show their parts in order, with the toolbar at the bottom and at the top"