From a2d84795a764c5fda329d80fb4b503e7762b2f83 Mon Sep 17 00:00:00 2001 From: Martin Vidner Date: Tue, 6 Oct 2020 15:03:06 +0200 Subject: [PATCH 01/16] Test table_sort_wrong_cell (bsc#1165388) using tmux-uitest.sh FIXME: resolve where tmux-uitest.sh belongs, give it some header and docs --- tests/libyui/README.md | 3 + tests/libyui/table_sort_wrong_cell_1165388 | 19 ++++ tests/libyui/table_sort_wrong_cell_1165388.rb | 41 +++++++++ tests/libyui/tmux-uitest.sh | 89 +++++++++++++++++++ 4 files changed, 152 insertions(+) create mode 100644 tests/libyui/README.md create mode 100755 tests/libyui/table_sort_wrong_cell_1165388 create mode 100755 tests/libyui/table_sort_wrong_cell_1165388.rb create mode 100644 tests/libyui/tmux-uitest.sh diff --git a/tests/libyui/README.md b/tests/libyui/README.md new file mode 100644 index 00000000..d43b50b2 --- /dev/null +++ b/tests/libyui/README.md @@ -0,0 +1,3 @@ + +- `foo` - main script of the test case +- `foo.rb` - UI set up diff --git a/tests/libyui/table_sort_wrong_cell_1165388 b/tests/libyui/table_sort_wrong_cell_1165388 new file mode 100755 index 00000000..f5006d68 --- /dev/null +++ b/tests/libyui/table_sort_wrong_cell_1165388 @@ -0,0 +1,19 @@ +#!/bin/sh +set -u # unset variables are an error +. ../examples/screenshots-tui/scripts/tmux-uitest.sh +BASE=table_sort_wrong_cell_1165388 + +tmux_new_session /usr/sbin/yast ./"$BASE".rb || exit +tmux_await "Table sorting test" || exit +sleep 0.1 # draw the rest of the screen + +tmux_send_keys Enter # activate first table row + +if ! tmux_grep "name-aaa.VALUE-AAA"; then + echo "The wrong cell was displayed, bug boo#1165388 exists" + tmux_send_keys M-C # &Close + exit 1 +fi + +tmux_send_keys M-C # &Close +exit 0 diff --git a/tests/libyui/table_sort_wrong_cell_1165388.rb b/tests/libyui/table_sort_wrong_cell_1165388.rb new file mode 100755 index 00000000..96c40984 --- /dev/null +++ b/tests/libyui/table_sort_wrong_cell_1165388.rb @@ -0,0 +1,41 @@ +#!/usr/sbin/yast +module Yast + class TableCellClient < Client + def main + Yast.import "UI" + + # notice that neither the ids nor the values are sorted here + contents = [ + Item(Id("id-zzz-1"), "name-bbb", "value-bbb"), + Item(Id("id-yyy-2"), "name-ccc", "value-ccc"), + Item(Id("id-xxx-3"), "name-aaa", "value-aaa"), + ] + keep_sorting = WFM.Args()[0] == "no-sort" + opts = keep_sorting ? Opt(:keepSorting, :notify) : Opt(:notify) + UI.OpenDialog( + VBox( + Label("Table sorting test"), + MinSize( + 25, 8, + Table(Id(:table), opts, Header("Name", "Value"), contents) + ), + Label("Enter/Double-click any item to uppercase the value"), + PushButton(Id(:cancel), "&Close") + ) + ) + + while UI.UserInput != :cancel + current_item_id = UI.QueryWidget(Id(:table), :CurrentItem) + value = UI.QueryWidget(:table, Cell(current_item_id, 1)) + UI.ChangeWidget(Id(:table), Cell(current_item_id, 1), value.upcase) + end + items = UI.QueryWidget(:table, :Items) + Builtins.y2milestone("Items: %1", items) + + UI.CloseDialog + nil + end + end +end + +Yast::TableCellClient.new.main diff --git a/tests/libyui/tmux-uitest.sh b/tests/libyui/tmux-uitest.sh new file mode 100644 index 00000000..19d9b2fa --- /dev/null +++ b/tests/libyui/tmux-uitest.sh @@ -0,0 +1,89 @@ +SESSION=uitest +: ${VERBOSE=false} + +# $@ commands +tmux_new_session() { + if $VERBOSE; then + echo Starting session + fi + # -s session name + # -x width -y height, + # -d detached + tmux new-session -s "$SESSION" -x 80 -y 24 -d "$@" +} + +# A --quiet grep +# $1 regex (POSIX ERE) to find in captured pane +# retcode: true or false +tmux_grep() { + local REGEX="$1" + tmux capture-pane -t "$SESSION" -p | grep -E --quiet "$REGEX" + RESULT=(${PIPESTATUS[@]}) + + if [ ${RESULT[0]} != 0 ]; then + # capturing the pane failed; the session may have exited already + return 2 + fi + + # capturing went fine, pass on the grep result + test ${RESULT[1]} = 0 +} + +# $1 regex (POSIX ERE) to find in captured pane +tmux_await() { + local REGEX="$1" + + local SLEEPS=(0.1 0.2 0.2 0.5 1 2 2 5) + for SL in "${SLEEPS[@]}"; do + tmux_grep "$REGEX" && return 0 + if [ $? = 2 ]; then return 2; fi # session not found + # text not found, continue waiting for it + sleep "$SL" + done + # text not found, timed out + false +} + +# $1 +# $1.txt plain text +# $1.esc text with escape sequences for colors +tmux_capture_pane() { + local OUT="$1" + + # -t target-pane, -p to stdout, + # -e escape sequences for text and background attributes + tmux capture-pane -t "$SESSION" -p -e > "$OUT.esc" + tmux capture-pane -t "$SESSION" -p > "$OUT.txt" + # this is racy. if it is a problem we should make .txt from .esc + # by filtering out the escape sequences +} + +# $1 keys ("C-X" for Ctrl-X, "M-X" for Alt-X, think "Meta"); for details see: +# man tmux | less +/"^KEY BINDINGS" +tmux_send_keys() { + if $VERBOSE; then + echo Sending "$1" + fi + # -t target-pane + tmux send-keys -t "$SESSION" "$1" +} + +# $1 session name +# ret code: true or false +tmux_has_session() { + if $VERBOSE; then + echo Detecting the session + fi + # -t target-session + tmux has-session -t "$SESSION" +} + + +# $1 session name +tmux_kill_session() { + if $VERBOSE; then + echo Killing the session + fi + # -t target-session + tmux kill-session -t "$SESSION" +} From 12c144db94e6e6f32a88e7ceb4a6d688cc88b491 Mon Sep 17 00:00:00 2001 From: Martin Vidner Date: Tue, 6 Oct 2020 15:09:21 +0200 Subject: [PATCH 02/16] Run the libyui tests --- package/yast2-ruby-bindings.spec | 6 +++--- tests/CMakeLists.txt | 16 ++++++++++++--- tests/libyui/README.md | 2 +- tests/libyui/table_sort_wrong_cell_1165388.rb | 12 ++++++++++- ...388 => table_sort_wrong_cell_1165388.test} | 12 +++++++++-- tests/libyui/tmux-uitest.sh | 20 +++++++++++++------ 6 files changed, 52 insertions(+), 16 deletions(-) rename tests/libyui/{table_sort_wrong_cell_1165388 => table_sort_wrong_cell_1165388.test} (60%) diff --git a/package/yast2-ruby-bindings.spec b/package/yast2-ruby-bindings.spec index 236a8e03..f474db98 100644 --- a/package/yast2-ruby-bindings.spec +++ b/package/yast2-ruby-bindings.spec @@ -46,9 +46,9 @@ BuildRequires: yast2-ycp-ui-bindings-devel >= 4.3.1 # The test suite includes a regression test (std_streams_spec.rb) for a # libyui-ncurses bug fixed in 2.47.3 BuildRequires: libyui-ncurses >= 2.47.3 -# The mentioned test requires to check if tmux is there, because tmux is -# needed to execute the test in headless systems -BuildRequires: which +# The mentioned test requires tmux in order to be executed in headless systems +# Also many other libyui tests to come +BuildRequires: tmux # only a soft dependency, the Ruby debugger is optional Suggests: rubygem(%{rb_default_ruby_abi}:byebug) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index a64eade2..5e78dfe4 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,6 +1,11 @@ -# -# CMakeLists.txt for yast2/ruby-bindings/tests/ruby -# +# CMakeLists.txt for yast-ruby-bindings/tests + +# use +# make test +# or, for verbose output, +# make test ARGS=-V +# ARGS is passed to ctest; see also +# man ctest ENABLE_TESTING() @@ -12,3 +17,8 @@ endforeach(test) ADD_TEST("integration" ruby ${CMAKE_CURRENT_SOURCE_DIR}/integration/run.rb) ADD_TEST("translations" rspec --format doc ${CMAKE_CURRENT_SOURCE_DIR}/integration/translations_spec.rb) + +file(GLOB libyui_tests "libyui/*.test") +foreach(test ${libyui_tests}) + ADD_TEST(${test} ${test}) +endforeach() diff --git a/tests/libyui/README.md b/tests/libyui/README.md index d43b50b2..aac945bc 100644 --- a/tests/libyui/README.md +++ b/tests/libyui/README.md @@ -1,3 +1,3 @@ -- `foo` - main script of the test case +- `foo.test` - main script of the test case - `foo.rb` - UI set up diff --git a/tests/libyui/table_sort_wrong_cell_1165388.rb b/tests/libyui/table_sort_wrong_cell_1165388.rb index 96c40984..5223d295 100755 --- a/tests/libyui/table_sort_wrong_cell_1165388.rb +++ b/tests/libyui/table_sort_wrong_cell_1165388.rb @@ -1,4 +1,14 @@ -#!/usr/sbin/yast +#! /usr/bin/env ruby + +# See table_sort_wrong_cell_1165388.test + +require_relative "../test_helper" +require "yast" + +if Yast.ui_component == "" + Yast.ui_component = ARGV[0] || "ncurses" +end + module Yast class TableCellClient < Client def main diff --git a/tests/libyui/table_sort_wrong_cell_1165388 b/tests/libyui/table_sort_wrong_cell_1165388.test similarity index 60% rename from tests/libyui/table_sort_wrong_cell_1165388 rename to tests/libyui/table_sort_wrong_cell_1165388.test index f5006d68..fadce668 100755 --- a/tests/libyui/table_sort_wrong_cell_1165388 +++ b/tests/libyui/table_sort_wrong_cell_1165388.test @@ -1,9 +1,17 @@ #!/bin/sh + +# Verify that changing a value in a sorted table works correctly. +# See https://bugzilla.opensuse.org/show_bug.cgi?id=1165388 + set -u # unset variables are an error -. ../examples/screenshots-tui/scripts/tmux-uitest.sh +MYDIR=$(dirname "$0") +# shellcheck source=/dev/null # that file is checked separately +. "$MYDIR"/tmux-uitest.sh BASE=table_sort_wrong_cell_1165388 -tmux_new_session /usr/sbin/yast ./"$BASE".rb || exit +tmux_new_session "$MYDIR"/"$BASE".rb || exit +trap tmux_cleanup EXIT + tmux_await "Table sorting test" || exit sleep 0.1 # draw the rest of the screen diff --git a/tests/libyui/tmux-uitest.sh b/tests/libyui/tmux-uitest.sh index 19d9b2fa..7e71253e 100644 --- a/tests/libyui/tmux-uitest.sh +++ b/tests/libyui/tmux-uitest.sh @@ -1,5 +1,8 @@ +#!/bin/bash +# tmux-uitest.sh - a shell library to test Text User Interface using tmux + SESSION=uitest -: ${VERBOSE=false} +: "${VERBOSE=false}" # $@ commands tmux_new_session() { @@ -18,15 +21,15 @@ tmux_new_session() { tmux_grep() { local REGEX="$1" tmux capture-pane -t "$SESSION" -p | grep -E --quiet "$REGEX" - RESULT=(${PIPESTATUS[@]}) + RESULT=("${PIPESTATUS[@]}") - if [ ${RESULT[0]} != 0 ]; then + if [ "${RESULT[0]}" != 0 ]; then # capturing the pane failed; the session may have exited already return 2 fi # capturing went fine, pass on the grep result - test ${RESULT[1]} = 0 + test "${RESULT[1]}" = 0 } # $1 regex (POSIX ERE) to find in captured pane @@ -68,7 +71,13 @@ tmux_send_keys() { tmux send-keys -t "$SESSION" "$1" } -# $1 session name +# usage: trap tmux_cleanup EXIT +tmux_cleanup() { + if tmux_has_session; then + tmux_kill_session + fi +} + # ret code: true or false tmux_has_session() { if $VERBOSE; then @@ -79,7 +88,6 @@ tmux_has_session() { } -# $1 session name tmux_kill_session() { if $VERBOSE; then echo Killing the session From eee00b3f0ec4018a9a2c5222c4885a750ce0224a Mon Sep 17 00:00:00 2001 From: Martin Vidner Date: Tue, 13 Oct 2020 16:44:15 +0200 Subject: [PATCH 03/16] version + changelog --- package/yast2-ruby-bindings.changes | 6 ++++++ package/yast2-ruby-bindings.spec | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/package/yast2-ruby-bindings.changes b/package/yast2-ruby-bindings.changes index f6ac855c..73294c87 100644 --- a/package/yast2-ruby-bindings.changes +++ b/package/yast2-ruby-bindings.changes @@ -1,3 +1,9 @@ +------------------------------------------------------------------- +Tue Oct 13 14:42:52 UTC 2020 - Martin Vidner + +- Add automatic TUI (ncurses) tests using tmux (bsc#1165388). +- 4.3.5 + ------------------------------------------------------------------- Thu Sep 24 19:46:00 UTC 2020 - besser82@fedoraproject.org diff --git a/package/yast2-ruby-bindings.spec b/package/yast2-ruby-bindings.spec index f474db98..005d31ac 100644 --- a/package/yast2-ruby-bindings.spec +++ b/package/yast2-ruby-bindings.spec @@ -17,7 +17,7 @@ Name: yast2-ruby-bindings -Version: 4.3.4 +Version: 4.3.5 Release: 0 URL: https://github.com/yast/yast-ruby-bindings BuildRoot: %{_tmppath}/%{name}-%{version}-build From 1b276124e62f10a6d15bdd0bb91d1bb14f820993 Mon Sep 17 00:00:00 2001 From: Martin Vidner Date: Thu, 15 Oct 2020 13:01:26 +0200 Subject: [PATCH 04/16] Optionally check shell syntax --- tests/libyui/shellcheck.test | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100755 tests/libyui/shellcheck.test diff --git a/tests/libyui/shellcheck.test b/tests/libyui/shellcheck.test new file mode 100755 index 00000000..5a20d382 --- /dev/null +++ b/tests/libyui/shellcheck.test @@ -0,0 +1,12 @@ +#!/bin/bash +set -e +set -u + +if ! type -P shellcheck >/dev/null; then + echo "SKIP https://www.shellcheck.net/ is not installed" + exit 0 +fi + +MYDIR=$(dirname "$0") +FILES=("$MYDIR"/*.test "$MYDIR"/tmux-uitest.sh) +shellcheck --wiki-link-count=99 "${FILES[@]}" From 1f9988953d546030d9ca69dd339e53905559821c Mon Sep 17 00:00:00 2001 From: Martin Vidner Date: Thu, 15 Oct 2020 16:30:47 +0200 Subject: [PATCH 05/16] tmux-uitest.sh: debug failed sessions --- tests/libyui/tmux-uitest.sh | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/tests/libyui/tmux-uitest.sh b/tests/libyui/tmux-uitest.sh index 7e71253e..a1756075 100644 --- a/tests/libyui/tmux-uitest.sh +++ b/tests/libyui/tmux-uitest.sh @@ -4,7 +4,7 @@ SESSION=uitest : "${VERBOSE=false}" -# $@ commands +# $1 shell command for sh -c tmux_new_session() { if $VERBOSE; then echo Starting session @@ -12,7 +12,8 @@ tmux_new_session() { # -s session name # -x width -y height, # -d detached - tmux new-session -s "$SESSION" -x 80 -y 24 -d "$@" + # FIXME: sleep to be able to see errors when running $1 + tmux new-session -s "$SESSION" -x 80 -y 24 -d sh -c "$1; sleep 9999" } # A --quiet grep @@ -47,10 +48,15 @@ tmux_await() { false } +# capture the session to stdout +tmux_capture_pane() { + tmux capture-pane -t "$SESSION" -p +} + # $1 # $1.txt plain text # $1.esc text with escape sequences for colors -tmux_capture_pane() { +tmux_capture_pane_to() { local OUT="$1" # -t target-pane, -p to stdout, @@ -74,6 +80,9 @@ tmux_send_keys() { # usage: trap tmux_cleanup EXIT tmux_cleanup() { if tmux_has_session; then + echo "SCREEN BEGIN (non-empty lines only)" + tmux_capture_pane | grep . + echo "SCREEN END" tmux_kill_session fi } From 79c25ff7fa432e8478475c2ed208751b2b497ec0 Mon Sep 17 00:00:00 2001 From: Martin Vidner Date: Fri, 16 Oct 2020 20:57:24 +0200 Subject: [PATCH 06/16] Test https://bugzilla.suse.com/show_bug.cgi?id=1177760 Menu items lose their hotkeys --- tests/libyui/menu_hotkeys_1177760.test | 37 ++++++++++++++ tests/libyui/table_sort_wrong_cell_1165388.rb | 51 ------------------- .../libyui/table_sort_wrong_cell_1165388.test | 27 ---------- 3 files changed, 37 insertions(+), 78 deletions(-) create mode 100755 tests/libyui/menu_hotkeys_1177760.test delete mode 100755 tests/libyui/table_sort_wrong_cell_1165388.rb delete mode 100755 tests/libyui/table_sort_wrong_cell_1165388.test diff --git a/tests/libyui/menu_hotkeys_1177760.test b/tests/libyui/menu_hotkeys_1177760.test new file mode 100755 index 00000000..50aada87 --- /dev/null +++ b/tests/libyui/menu_hotkeys_1177760.test @@ -0,0 +1,37 @@ +#!/bin/sh + +# Test https://bugzilla.suse.com/show_bug.cgi?id=1177760 +# Menu items lose their hotkeys + +set -u # unset variables are an error +MYDIR=$(dirname "$0") +# shellcheck source=/dev/null # that file is checked separately +. "$MYDIR"/tmux-uitest.sh +BUG=1177760 +BASE=menu_hotkeys_$BUG + +tmux_new_session "/usr/sbin/yast /usr/share/doc/packages/yast2-ycp-ui-bindings/examples/MenuBar1.rb" || exit +trap tmux_cleanup EXIT + +tmux_await "File.*Edit.*View" || exit +sleep 0.1 # draw the rest of the screen +tmux_capture_pane_to "${BASE}-1-initial" + +tmux_send_keys M-V # &View +tmux_capture_pane_to "${BASE}-2-view-menu-activated" + +tmux_send_keys M-N # &Normal +tmux_capture_pane_to "${BASE}-3-normal-menu-item-activated" + +if ! tmux_grep "Last Event"; then + echo "The script does not echo what it should" + exit 1 +fi + +if ! tmux_grep "view_normal"; then + echo "view_normal was not activated, bug boo#$BUG exists" + exit 1 +fi + +tmux_send_keys M-Q # &Quit +exit 0 diff --git a/tests/libyui/table_sort_wrong_cell_1165388.rb b/tests/libyui/table_sort_wrong_cell_1165388.rb deleted file mode 100755 index 5223d295..00000000 --- a/tests/libyui/table_sort_wrong_cell_1165388.rb +++ /dev/null @@ -1,51 +0,0 @@ -#! /usr/bin/env ruby - -# See table_sort_wrong_cell_1165388.test - -require_relative "../test_helper" -require "yast" - -if Yast.ui_component == "" - Yast.ui_component = ARGV[0] || "ncurses" -end - -module Yast - class TableCellClient < Client - def main - Yast.import "UI" - - # notice that neither the ids nor the values are sorted here - contents = [ - Item(Id("id-zzz-1"), "name-bbb", "value-bbb"), - Item(Id("id-yyy-2"), "name-ccc", "value-ccc"), - Item(Id("id-xxx-3"), "name-aaa", "value-aaa"), - ] - keep_sorting = WFM.Args()[0] == "no-sort" - opts = keep_sorting ? Opt(:keepSorting, :notify) : Opt(:notify) - UI.OpenDialog( - VBox( - Label("Table sorting test"), - MinSize( - 25, 8, - Table(Id(:table), opts, Header("Name", "Value"), contents) - ), - Label("Enter/Double-click any item to uppercase the value"), - PushButton(Id(:cancel), "&Close") - ) - ) - - while UI.UserInput != :cancel - current_item_id = UI.QueryWidget(Id(:table), :CurrentItem) - value = UI.QueryWidget(:table, Cell(current_item_id, 1)) - UI.ChangeWidget(Id(:table), Cell(current_item_id, 1), value.upcase) - end - items = UI.QueryWidget(:table, :Items) - Builtins.y2milestone("Items: %1", items) - - UI.CloseDialog - nil - end - end -end - -Yast::TableCellClient.new.main diff --git a/tests/libyui/table_sort_wrong_cell_1165388.test b/tests/libyui/table_sort_wrong_cell_1165388.test deleted file mode 100755 index fadce668..00000000 --- a/tests/libyui/table_sort_wrong_cell_1165388.test +++ /dev/null @@ -1,27 +0,0 @@ -#!/bin/sh - -# Verify that changing a value in a sorted table works correctly. -# See https://bugzilla.opensuse.org/show_bug.cgi?id=1165388 - -set -u # unset variables are an error -MYDIR=$(dirname "$0") -# shellcheck source=/dev/null # that file is checked separately -. "$MYDIR"/tmux-uitest.sh -BASE=table_sort_wrong_cell_1165388 - -tmux_new_session "$MYDIR"/"$BASE".rb || exit -trap tmux_cleanup EXIT - -tmux_await "Table sorting test" || exit -sleep 0.1 # draw the rest of the screen - -tmux_send_keys Enter # activate first table row - -if ! tmux_grep "name-aaa.VALUE-AAA"; then - echo "The wrong cell was displayed, bug boo#1165388 exists" - tmux_send_keys M-C # &Close - exit 1 -fi - -tmux_send_keys M-C # &Close -exit 0 From 55a3d2b40ee982718940aea8effd45afbd0af49c Mon Sep 17 00:00:00 2001 From: Martin Vidner Date: Fri, 16 Oct 2020 21:04:39 +0200 Subject: [PATCH 07/16] Run without /usr/sbin/yast --- tests/libyui/menu_hotkeys_1177760.test | 2 +- tests/libyui/yast_ncurses | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100755 tests/libyui/yast_ncurses diff --git a/tests/libyui/menu_hotkeys_1177760.test b/tests/libyui/menu_hotkeys_1177760.test index 50aada87..a5f19593 100755 --- a/tests/libyui/menu_hotkeys_1177760.test +++ b/tests/libyui/menu_hotkeys_1177760.test @@ -10,7 +10,7 @@ MYDIR=$(dirname "$0") BUG=1177760 BASE=menu_hotkeys_$BUG -tmux_new_session "/usr/sbin/yast /usr/share/doc/packages/yast2-ycp-ui-bindings/examples/MenuBar1.rb" || exit +tmux_new_session "${MYDIR}/yast_ncurses /usr/share/doc/packages/yast2-ycp-ui-bindings/examples/MenuBar1.rb" || exit trap tmux_cleanup EXIT tmux_await "File.*Edit.*View" || exit diff --git a/tests/libyui/yast_ncurses b/tests/libyui/yast_ncurses new file mode 100755 index 00000000..5cc5a596 --- /dev/null +++ b/tests/libyui/yast_ncurses @@ -0,0 +1,5 @@ +#! /usr/bin/env ruby +require_relative "../test_helper" +require "yast" +Yast.ui_component = "ncurses" +load ARGV[0] From b60f2bb72685ec74baea744070d4ca0eb47ee3ca Mon Sep 17 00:00:00 2001 From: Martin Vidner Date: Mon, 19 Oct 2020 09:13:30 +0200 Subject: [PATCH 08/16] Fixup container test run The example UI scripts that we are starting to use for testing are marked as docs in the RPM and the container images exclude them. Explicitly install them. --- Dockerfile | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Dockerfile b/Dockerfile index 2fe681f4..3d914607 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,4 +2,9 @@ FROM registry.opensuse.org/yast/head/containers/yast-cpp:latest # Install tmux to make sure the libyui+YaST integration tests are run RUN zypper --non-interactive in tmux +# Enable installing docs... +RUN sed -i 's/\(rpm\.install\.excludedocs =\).*/\1 no/' /etc/zypp/zypp.conf +# ... and reinstall the RPM containing the examples we use for tests +RUN zypper --non-interactive in --force yast2-ycp-ui-bindings-devel + COPY . /usr/src/app From e2fa1a5d1987f3f8b297223d6937e22d5104efe4 Mon Sep 17 00:00:00 2001 From: Martin Vidner Date: Wed, 21 Oct 2020 10:11:09 +0200 Subject: [PATCH 09/16] RSpec test with TmuxTui --- tests/CMakeLists.txt | 5 ++ tests/libyui/menu_hotkeys_1177760_spec.rb | 36 +++++++++++ tests/libyui/rspec_tmux_tui.rb | 76 +++++++++++++++++++++++ 3 files changed, 117 insertions(+) create mode 100755 tests/libyui/menu_hotkeys_1177760_spec.rb create mode 100644 tests/libyui/rspec_tmux_tui.rb diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 5e78dfe4..488d72c8 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -18,6 +18,11 @@ endforeach(test) ADD_TEST("integration" ruby ${CMAKE_CURRENT_SOURCE_DIR}/integration/run.rb) ADD_TEST("translations" rspec --format doc ${CMAKE_CURRENT_SOURCE_DIR}/integration/translations_spec.rb) +file(GLOB libyui_specs "libyui/*_spec.rb") +foreach(test ${libyui_specs}) + ADD_TEST(${test} rspec --format doc ${test}) +endforeach(test) + file(GLOB libyui_tests "libyui/*.test") foreach(test ${libyui_tests}) ADD_TEST(${test} ${test}) diff --git a/tests/libyui/menu_hotkeys_1177760_spec.rb b/tests/libyui/menu_hotkeys_1177760_spec.rb new file mode 100755 index 00000000..07beae56 --- /dev/null +++ b/tests/libyui/menu_hotkeys_1177760_spec.rb @@ -0,0 +1,36 @@ +require_relative "rspec_tmux_tui" + +describe "Menu Item" do + bug = "1177760" + around(:each) do |ex| + @base = "menu_hotkeys_#{bug}" + + yast_ncurses = "#{__dir__}/yast_ncurses" + example_dir = "/usr/share/doc/packages/yast2-ycp-ui-bindings/examples" + @tui = TmuxTui.new_session "#{yast_ncurses} #{example_dir}/MenuBar1.rb" + + ex.run + + if @tui.has_session? + @tui.kill_session + end + end + + it "has hotkeys in menu items, boo##{bug}" do + @tui.await(/File.*Edit.*View/) + @tui.capture_pane_to("#{@base}-1-initial") + + @tui.send_keys "M-V" # &View + @tui.capture_pane_to("#{@base}-2-view-menu-activated") + + @tui.send_keys "M-N" # &Normal + @tui.capture_pane_to("#{@base}-3-normal-menu-item-activated") + + # the label + expect(@tui.capture_pane).to include("Last Event") + # the output + expect(@tui.capture_pane).to include("view_normal") + + @tui.send_keys "M-Q" # &Quit + end +end diff --git a/tests/libyui/rspec_tmux_tui.rb b/tests/libyui/rspec_tmux_tui.rb new file mode 100644 index 00000000..caaf97b3 --- /dev/null +++ b/tests/libyui/rspec_tmux_tui.rb @@ -0,0 +1,76 @@ +require "shellwords" + +class TmuxTui + class Error < RuntimeError + end + + def self.new_session(*args) + new(*args) + end + + attr_reader :session_name + + def initialize(shell_command, x: 80, y: 24, detach: true, session_name: nil) + @shell_command = shell_command + @x = x + @y = y + @detach = detach + @session_name = session_name || new_session_name + + system "tmux", "new-session", + "-s", @session_name, + "-x", @x.to_s, + "-y", @y.to_s, + *(@detach ? ["-d"] : [] ), + "sh", "-c", "#{@shell_command}; sleep 9999" + end + + def new_session_name + "tmux-tui-#{rand 10000}" + end + + # @return [String] + def capture_pane(color: false) + esc = color ? "-e" : "" + # FIXME: failure of the command? + `tmux capture-pane -t #{session_name.shellescape} -p #{esc}` + end + + def capture_pane_to(filename) + txt = capture_pane(color: false) + esc = capture_pane(color: true) + File.write("#{filename}.txt", txt) + File.write("#{filename}.esc", esc) + end + + def await(pattern) + sleeps = [0.1, 0.2, 0.2, 0.5, 1, 2, 2, 5] + txt = "" + sleeps.each do |sl| + txt = capture_pane + case txt + when pattern + sleep 0.1 # draw the rest of the screen + return + else + sleep sl + end + end + raise Error, "Timed out waiting for #{pattern.inspect}. Seen:\n#{txt}" + end + + # @param keys [String] "C-X" for Ctrl-X, "M-X" for Alt-X, think "Meta"; + # for details see: + # man tmux | less +/"^KEY BINDINGS" + def send_keys(keys) + system "tmux", "send-keys", "-t", session_name, keys + end + + def has_session? + system "tmux", "has-session", "-t", session_name + end + + def kill_session + system "tmux", "kill-session", "-t", session_name + end +end From 89b2eaf4673d2eda3aabba8b5362612ae5b6cab5 Mon Sep 17 00:00:00 2001 From: Martin Vidner Date: Wed, 21 Oct 2020 17:25:06 +0200 Subject: [PATCH 10/16] Verify that changing a value in a sorted table works correctly. (RSpec) See https://bugzilla.opensuse.org/show_bug.cgi?id=1165388 --- tests/libyui/table_sort.rb | 51 +++++++++++++++++++++++++++++++++ tests/libyui/table_sort_spec.rb | 29 +++++++++++++++++++ 2 files changed, 80 insertions(+) create mode 100755 tests/libyui/table_sort.rb create mode 100755 tests/libyui/table_sort_spec.rb diff --git a/tests/libyui/table_sort.rb b/tests/libyui/table_sort.rb new file mode 100755 index 00000000..5223d295 --- /dev/null +++ b/tests/libyui/table_sort.rb @@ -0,0 +1,51 @@ +#! /usr/bin/env ruby + +# See table_sort_wrong_cell_1165388.test + +require_relative "../test_helper" +require "yast" + +if Yast.ui_component == "" + Yast.ui_component = ARGV[0] || "ncurses" +end + +module Yast + class TableCellClient < Client + def main + Yast.import "UI" + + # notice that neither the ids nor the values are sorted here + contents = [ + Item(Id("id-zzz-1"), "name-bbb", "value-bbb"), + Item(Id("id-yyy-2"), "name-ccc", "value-ccc"), + Item(Id("id-xxx-3"), "name-aaa", "value-aaa"), + ] + keep_sorting = WFM.Args()[0] == "no-sort" + opts = keep_sorting ? Opt(:keepSorting, :notify) : Opt(:notify) + UI.OpenDialog( + VBox( + Label("Table sorting test"), + MinSize( + 25, 8, + Table(Id(:table), opts, Header("Name", "Value"), contents) + ), + Label("Enter/Double-click any item to uppercase the value"), + PushButton(Id(:cancel), "&Close") + ) + ) + + while UI.UserInput != :cancel + current_item_id = UI.QueryWidget(Id(:table), :CurrentItem) + value = UI.QueryWidget(:table, Cell(current_item_id, 1)) + UI.ChangeWidget(Id(:table), Cell(current_item_id, 1), value.upcase) + end + items = UI.QueryWidget(:table, :Items) + Builtins.y2milestone("Items: %1", items) + + UI.CloseDialog + nil + end + end +end + +Yast::TableCellClient.new.main diff --git a/tests/libyui/table_sort_spec.rb b/tests/libyui/table_sort_spec.rb new file mode 100755 index 00000000..30b47916 --- /dev/null +++ b/tests/libyui/table_sort_spec.rb @@ -0,0 +1,29 @@ +require_relative "rspec_tmux_tui" + +describe "Table" do + context "when it sorts the items," do + around(:each) do |ex| + yast_ncurses = "#{__dir__}/yast_ncurses" + @base = "table_sort" + @tui = TmuxTui.new_session "#{yast_ncurses} #{__dir__}/#{@base}.rb" + ex.run + @tui.kill_session if @tui.has_session? + end + + bug = "1165388" + it "ChangeWidget(_, Cell(row, col)) changes the correct cell, boo##{bug}" do + @tui.await(/Table sorting test/) + @tui.capture_pane_to("#{@base}-1-initial") + + @tui.send_keys "Home" # go to first table row + @tui.capture_pane_to("#{@base}-2-first-row-selected") + + @tui.send_keys "Enter" # activate first table row + @tui.capture_pane_to("#{@base}-3-first-row-activated") + + expect(@tui.capture_pane).to match(/name-aaa.VALUE-AAA/) + + @tui.send_keys "M-C" # &Close + end + end +end From 7c7d1938af86530d1470a54193edda4e5f6f5c17 Mon Sep 17 00:00:00 2001 From: Martin Vidner Date: Wed, 21 Oct 2020 17:25:37 +0200 Subject: [PATCH 11/16] Ignore the screen captures --- .gitignore | 3 +++ tests/libyui/rspec_tmux_tui.rb | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 780df590..c67ae5ae 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,6 @@ /.yardoc /package/*.tar.* *.pot +# screen captures from the libyui tests +*.out.txt +*.out.esc diff --git a/tests/libyui/rspec_tmux_tui.rb b/tests/libyui/rspec_tmux_tui.rb index caaf97b3..0fc3de4a 100644 --- a/tests/libyui/rspec_tmux_tui.rb +++ b/tests/libyui/rspec_tmux_tui.rb @@ -39,8 +39,8 @@ def capture_pane(color: false) def capture_pane_to(filename) txt = capture_pane(color: false) esc = capture_pane(color: true) - File.write("#{filename}.txt", txt) - File.write("#{filename}.esc", esc) + File.write("#{filename}.out.txt", txt) + File.write("#{filename}.out.esc", esc) end def await(pattern) From 50ba537313ca660536b491a84f95379188b23c74 Mon Sep 17 00:00:00 2001 From: Martin Vidner Date: Wed, 21 Oct 2020 19:40:04 +0200 Subject: [PATCH 12/16] Added a (skipped) test for boo#1177145, wrong item is selected --- tests/libyui/table_sort.rb | 21 ++++++++++++++++----- tests/libyui/table_sort_spec.rb | 26 ++++++++++++++++++++++---- 2 files changed, 38 insertions(+), 9 deletions(-) diff --git a/tests/libyui/table_sort.rb b/tests/libyui/table_sort.rb index 5223d295..dcaf8b6a 100755 --- a/tests/libyui/table_sort.rb +++ b/tests/libyui/table_sort.rb @@ -1,7 +1,5 @@ #! /usr/bin/env ruby -# See table_sort_wrong_cell_1165388.test - require_relative "../test_helper" require "yast" @@ -16,9 +14,9 @@ def main # notice that neither the ids nor the values are sorted here contents = [ - Item(Id("id-zzz-1"), "name-bbb", "value-bbb"), - Item(Id("id-yyy-2"), "name-ccc", "value-ccc"), - Item(Id("id-xxx-3"), "name-aaa", "value-aaa"), + Item(Id("id-zzz-1-bbb"), "name-bbb", "value-bbb"), + Item(Id("id-yyy-2-ccc"), "name-ccc", "value-ccc"), + Item(Id("id-xxx-3-aaa"), "name-aaa", "value-aaa"), ] keep_sorting = WFM.Args()[0] == "no-sort" opts = keep_sorting ? Opt(:keepSorting, :notify) : Opt(:notify) @@ -30,12 +28,25 @@ def main Table(Id(:table), opts, Header("Name", "Value"), contents) ), Label("Enter/Double-click any item to uppercase the value"), + HBox( + HSquash(Label("Current Item: ")), + Label(Id(:current_item), Opt(:outputField, :hstretch), "...") + ), PushButton(Id(:cancel), "&Close") ) ) + if WFM.Args()[0] == "change-current-item" + # test boo#1177145, wrong item is selected + UI.ChangeWidget(Id(:table), :CurrentItem, "id-yyy-2-ccc") + current_item_id = UI.QueryWidget(Id(:table), :CurrentItem) + UI.ChangeWidget(Id(:current_item), :Value, current_item_id.inspect) + end + while UI.UserInput != :cancel current_item_id = UI.QueryWidget(Id(:table), :CurrentItem) + UI.ChangeWidget(Id(:current_item), :Value, current_item_id.inspect) + value = UI.QueryWidget(:table, Cell(current_item_id, 1)) UI.ChangeWidget(Id(:table), Cell(current_item_id, 1), value.upcase) end diff --git a/tests/libyui/table_sort_spec.rb b/tests/libyui/table_sort_spec.rb index 30b47916..a292e395 100755 --- a/tests/libyui/table_sort_spec.rb +++ b/tests/libyui/table_sort_spec.rb @@ -5,25 +5,43 @@ around(:each) do |ex| yast_ncurses = "#{__dir__}/yast_ncurses" @base = "table_sort" - @tui = TmuxTui.new_session "#{yast_ncurses} #{__dir__}/#{@base}.rb" + @tui = TmuxTui.new_session "#{yast_ncurses} #{__dir__}/#{@base}.rb change-current-item" ex.run @tui.kill_session if @tui.has_session? end bug = "1165388" it "ChangeWidget(_, Cell(row, col)) changes the correct cell, boo##{bug}" do + base = @base + "_cell" @tui.await(/Table sorting test/) - @tui.capture_pane_to("#{@base}-1-initial") + @tui.capture_pane_to("#{base}-1-initial") @tui.send_keys "Home" # go to first table row - @tui.capture_pane_to("#{@base}-2-first-row-selected") + @tui.capture_pane_to("#{base}-2-first-row-selected") @tui.send_keys "Enter" # activate first table row - @tui.capture_pane_to("#{@base}-3-first-row-activated") + @tui.capture_pane_to("#{base}-3-first-row-activated") expect(@tui.capture_pane).to match(/name-aaa.VALUE-AAA/) @tui.send_keys "M-C" # &Close end + + bug = "1177145" + it "ChangeWidget(_, :CurrentItem) activates the correct line, boo##{bug}" do + skip "not fixed yet" + + base = @base + "_current_item" + @tui.await(/Table sorting test/) + @tui.capture_pane_to("#{base}-1-ccc-selected") + # the UI code performs a + # UI.ChangeWidget(Id(:table), :CurrentItem, "id-yyy-2-ccc") + # then + # UI.QueryWidget(Id(:table), :CurrentItem) + @tui.send_keys "Enter" # activate the current item to produce an event + expect(@tui.capture_pane).to match(/Current Item: "id-yyy-2-ccc"/) + + @tui.send_keys "M-C" # &Close + end end end From c660d1adc4ba0e627da4a621bd220388240d4891 Mon Sep 17 00:00:00 2001 From: Martin Vidner Date: Wed, 21 Oct 2020 19:40:58 +0200 Subject: [PATCH 13/16] Remove shell tests and library, RSpec can do it now --- tests/CMakeLists.txt | 5 -- tests/libyui/README.md | 3 - tests/libyui/menu_hotkeys_1177760.test | 37 --------- tests/libyui/shellcheck.test | 12 --- tests/libyui/tmux-uitest.sh | 106 ------------------------- 5 files changed, 163 deletions(-) delete mode 100644 tests/libyui/README.md delete mode 100755 tests/libyui/menu_hotkeys_1177760.test delete mode 100755 tests/libyui/shellcheck.test delete mode 100644 tests/libyui/tmux-uitest.sh diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 488d72c8..913d9d7f 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -22,8 +22,3 @@ file(GLOB libyui_specs "libyui/*_spec.rb") foreach(test ${libyui_specs}) ADD_TEST(${test} rspec --format doc ${test}) endforeach(test) - -file(GLOB libyui_tests "libyui/*.test") -foreach(test ${libyui_tests}) - ADD_TEST(${test} ${test}) -endforeach() diff --git a/tests/libyui/README.md b/tests/libyui/README.md deleted file mode 100644 index aac945bc..00000000 --- a/tests/libyui/README.md +++ /dev/null @@ -1,3 +0,0 @@ - -- `foo.test` - main script of the test case -- `foo.rb` - UI set up diff --git a/tests/libyui/menu_hotkeys_1177760.test b/tests/libyui/menu_hotkeys_1177760.test deleted file mode 100755 index a5f19593..00000000 --- a/tests/libyui/menu_hotkeys_1177760.test +++ /dev/null @@ -1,37 +0,0 @@ -#!/bin/sh - -# Test https://bugzilla.suse.com/show_bug.cgi?id=1177760 -# Menu items lose their hotkeys - -set -u # unset variables are an error -MYDIR=$(dirname "$0") -# shellcheck source=/dev/null # that file is checked separately -. "$MYDIR"/tmux-uitest.sh -BUG=1177760 -BASE=menu_hotkeys_$BUG - -tmux_new_session "${MYDIR}/yast_ncurses /usr/share/doc/packages/yast2-ycp-ui-bindings/examples/MenuBar1.rb" || exit -trap tmux_cleanup EXIT - -tmux_await "File.*Edit.*View" || exit -sleep 0.1 # draw the rest of the screen -tmux_capture_pane_to "${BASE}-1-initial" - -tmux_send_keys M-V # &View -tmux_capture_pane_to "${BASE}-2-view-menu-activated" - -tmux_send_keys M-N # &Normal -tmux_capture_pane_to "${BASE}-3-normal-menu-item-activated" - -if ! tmux_grep "Last Event"; then - echo "The script does not echo what it should" - exit 1 -fi - -if ! tmux_grep "view_normal"; then - echo "view_normal was not activated, bug boo#$BUG exists" - exit 1 -fi - -tmux_send_keys M-Q # &Quit -exit 0 diff --git a/tests/libyui/shellcheck.test b/tests/libyui/shellcheck.test deleted file mode 100755 index 5a20d382..00000000 --- a/tests/libyui/shellcheck.test +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/bash -set -e -set -u - -if ! type -P shellcheck >/dev/null; then - echo "SKIP https://www.shellcheck.net/ is not installed" - exit 0 -fi - -MYDIR=$(dirname "$0") -FILES=("$MYDIR"/*.test "$MYDIR"/tmux-uitest.sh) -shellcheck --wiki-link-count=99 "${FILES[@]}" diff --git a/tests/libyui/tmux-uitest.sh b/tests/libyui/tmux-uitest.sh deleted file mode 100644 index a1756075..00000000 --- a/tests/libyui/tmux-uitest.sh +++ /dev/null @@ -1,106 +0,0 @@ -#!/bin/bash -# tmux-uitest.sh - a shell library to test Text User Interface using tmux - -SESSION=uitest -: "${VERBOSE=false}" - -# $1 shell command for sh -c -tmux_new_session() { - if $VERBOSE; then - echo Starting session - fi - # -s session name - # -x width -y height, - # -d detached - # FIXME: sleep to be able to see errors when running $1 - tmux new-session -s "$SESSION" -x 80 -y 24 -d sh -c "$1; sleep 9999" -} - -# A --quiet grep -# $1 regex (POSIX ERE) to find in captured pane -# retcode: true or false -tmux_grep() { - local REGEX="$1" - tmux capture-pane -t "$SESSION" -p | grep -E --quiet "$REGEX" - RESULT=("${PIPESTATUS[@]}") - - if [ "${RESULT[0]}" != 0 ]; then - # capturing the pane failed; the session may have exited already - return 2 - fi - - # capturing went fine, pass on the grep result - test "${RESULT[1]}" = 0 -} - -# $1 regex (POSIX ERE) to find in captured pane -tmux_await() { - local REGEX="$1" - - local SLEEPS=(0.1 0.2 0.2 0.5 1 2 2 5) - for SL in "${SLEEPS[@]}"; do - tmux_grep "$REGEX" && return 0 - if [ $? = 2 ]; then return 2; fi # session not found - # text not found, continue waiting for it - sleep "$SL" - done - # text not found, timed out - false -} - -# capture the session to stdout -tmux_capture_pane() { - tmux capture-pane -t "$SESSION" -p -} - -# $1 -# $1.txt plain text -# $1.esc text with escape sequences for colors -tmux_capture_pane_to() { - local OUT="$1" - - # -t target-pane, -p to stdout, - # -e escape sequences for text and background attributes - tmux capture-pane -t "$SESSION" -p -e > "$OUT.esc" - tmux capture-pane -t "$SESSION" -p > "$OUT.txt" - # this is racy. if it is a problem we should make .txt from .esc - # by filtering out the escape sequences -} - -# $1 keys ("C-X" for Ctrl-X, "M-X" for Alt-X, think "Meta"); for details see: -# man tmux | less +/"^KEY BINDINGS" -tmux_send_keys() { - if $VERBOSE; then - echo Sending "$1" - fi - # -t target-pane - tmux send-keys -t "$SESSION" "$1" -} - -# usage: trap tmux_cleanup EXIT -tmux_cleanup() { - if tmux_has_session; then - echo "SCREEN BEGIN (non-empty lines only)" - tmux_capture_pane | grep . - echo "SCREEN END" - tmux_kill_session - fi -} - -# ret code: true or false -tmux_has_session() { - if $VERBOSE; then - echo Detecting the session - fi - # -t target-session - tmux has-session -t "$SESSION" -} - - -tmux_kill_session() { - if $VERBOSE; then - echo Killing the session - fi - # -t target-session - tmux kill-session -t "$SESSION" -} From 12eb4539f518024cec7003a4c6f1c3b9449736ce Mon Sep 17 00:00:00 2001 From: Martin Vidner Date: Mon, 26 Oct 2020 16:18:19 +0100 Subject: [PATCH 14/16] Style improvements --- tests/libyui/menu_hotkeys_1177760_spec.rb | 6 ++---- tests/libyui/rspec_tmux_tui.rb | 13 +++++++++---- tests/libyui/table_sort_spec.rb | 8 ++++---- 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/tests/libyui/menu_hotkeys_1177760_spec.rb b/tests/libyui/menu_hotkeys_1177760_spec.rb index 07beae56..ec278335 100755 --- a/tests/libyui/menu_hotkeys_1177760_spec.rb +++ b/tests/libyui/menu_hotkeys_1177760_spec.rb @@ -1,7 +1,7 @@ require_relative "rspec_tmux_tui" describe "Menu Item" do - bug = "1177760" + bug = "1177760" # https://bugzilla.suse.com/show_bug.cgi?id=1177760 around(:each) do |ex| @base = "menu_hotkeys_#{bug}" @@ -11,9 +11,7 @@ ex.run - if @tui.has_session? - @tui.kill_session - end + @tui.ensure_no_session end it "has hotkeys in menu items, boo##{bug}" do diff --git a/tests/libyui/rspec_tmux_tui.rb b/tests/libyui/rspec_tmux_tui.rb index 0fc3de4a..85bac87a 100644 --- a/tests/libyui/rspec_tmux_tui.rb +++ b/tests/libyui/rspec_tmux_tui.rb @@ -50,8 +50,8 @@ def await(pattern) txt = capture_pane case txt when pattern - sleep 0.1 # draw the rest of the screen - return + sleep 0.1 # draw the rest of the screen + return nil else sleep sl end @@ -65,12 +65,17 @@ def await(pattern) def send_keys(keys) system "tmux", "send-keys", "-t", session_name, keys end - - def has_session? + + def has_session? # rubocop:disable Style/PredicateName + # the method name mimics the tmux command system "tmux", "has-session", "-t", session_name end def kill_session system "tmux", "kill-session", "-t", session_name end + + def ensure_no_session + kill_session if has_session? + end end diff --git a/tests/libyui/table_sort_spec.rb b/tests/libyui/table_sort_spec.rb index a292e395..a7bbccbf 100755 --- a/tests/libyui/table_sort_spec.rb +++ b/tests/libyui/table_sort_spec.rb @@ -7,10 +7,10 @@ @base = "table_sort" @tui = TmuxTui.new_session "#{yast_ncurses} #{__dir__}/#{@base}.rb change-current-item" ex.run - @tui.kill_session if @tui.has_session? + @tui.ensure_no_session end - bug = "1165388" + bug = "1165388" # https://bugzilla.suse.com/show_bug.cgi?id=1165388 it "ChangeWidget(_, Cell(row, col)) changes the correct cell, boo##{bug}" do base = @base + "_cell" @tui.await(/Table sorting test/) @@ -27,9 +27,9 @@ @tui.send_keys "M-C" # &Close end - bug = "1177145" + bug = "1177145" # https://bugzilla.suse.com/show_bug.cgi?id=1177145 it "ChangeWidget(_, :CurrentItem) activates the correct line, boo##{bug}" do - skip "not fixed yet" + pending "not fixed yet" base = @base + "_current_item" @tui.await(/Table sorting test/) From d3f08eb9704a9502ccf8971c32893a524e9f8e96 Mon Sep 17 00:00:00 2001 From: Martin Vidner Date: Mon, 26 Oct 2020 16:18:29 +0100 Subject: [PATCH 15/16] Use remain-on-exit instead of shell sleep. "remain-on-exit" is useful if shell_command may unexpectedly fail quickly. In that case we can still capture the pane and read the error messages. --- tests/libyui/rspec_tmux_tui.rb | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/tests/libyui/rspec_tmux_tui.rb b/tests/libyui/rspec_tmux_tui.rb index 85bac87a..c31f75cd 100644 --- a/tests/libyui/rspec_tmux_tui.rb +++ b/tests/libyui/rspec_tmux_tui.rb @@ -10,19 +10,31 @@ def self.new_session(*args) attr_reader :session_name - def initialize(shell_command, x: 80, y: 24, detach: true, session_name: nil) + def initialize(shell_command, + xy: [80, 24], detach: true, remain_on_exit: true, session_name: nil) + @shell_command = shell_command - @x = x - @y = y + @x, @y = xy @detach = detach @session_name = session_name || new_session_name - system "tmux", "new-session", - "-s", @session_name, - "-x", @x.to_s, - "-y", @y.to_s, - *(@detach ? ["-d"] : [] ), - "sh", "-c", "#{@shell_command}; sleep 9999" + detach_args = @detach ? ["-d"] : [] + # "remain-on-exit" is useful if shell_command may unexpectedly fail quickly. + # In that case we can still capture the pane and read the error messages. + remain_on_exit_args = if remain_on_exit + ["set-hook", "-g", "session-created", "set remain-on-exit on", ";"] + else + [] + end + + system "tmux", + * remain_on_exit_args, + "new-session", + "-s", @session_name, + "-x", @x.to_s, + "-y", @y.to_s, + * detach_args, + "sh", "-c", shell_command end def new_session_name From 387c97036488b4f4a3ce0d090c034164f17cddd7 Mon Sep 17 00:00:00 2001 From: Martin Vidner Date: Tue, 27 Oct 2020 10:54:49 +0100 Subject: [PATCH 16/16] Automatic session cleanup with a block; YastTui#example. --- tests/libyui/menu_hotkeys_1177760_spec.rb | 12 +++----- tests/libyui/rspec_tmux_tui.rb | 37 +++++++++++++++++++---- tests/libyui/table_sort_spec.rb | 7 +++-- 3 files changed, 39 insertions(+), 17 deletions(-) diff --git a/tests/libyui/menu_hotkeys_1177760_spec.rb b/tests/libyui/menu_hotkeys_1177760_spec.rb index ec278335..f9e09020 100755 --- a/tests/libyui/menu_hotkeys_1177760_spec.rb +++ b/tests/libyui/menu_hotkeys_1177760_spec.rb @@ -4,14 +4,10 @@ bug = "1177760" # https://bugzilla.suse.com/show_bug.cgi?id=1177760 around(:each) do |ex| @base = "menu_hotkeys_#{bug}" - - yast_ncurses = "#{__dir__}/yast_ncurses" - example_dir = "/usr/share/doc/packages/yast2-ycp-ui-bindings/examples" - @tui = TmuxTui.new_session "#{yast_ncurses} #{example_dir}/MenuBar1.rb" - - ex.run - - @tui.ensure_no_session + @tui = YastTui.new + @tui.example("MenuBar1") do + ex.run + end end it "has hotkeys in menu items, boo##{bug}" do diff --git a/tests/libyui/rspec_tmux_tui.rb b/tests/libyui/rspec_tmux_tui.rb index c31f75cd..f466cd3f 100644 --- a/tests/libyui/rspec_tmux_tui.rb +++ b/tests/libyui/rspec_tmux_tui.rb @@ -1,5 +1,7 @@ require "shellwords" +# Drive interactive TUI (textual user interface) with tmux. +# https://github.com/tmux/tmux class TmuxTui class Error < RuntimeError end @@ -10,24 +12,32 @@ def self.new_session(*args) attr_reader :session_name - def initialize(shell_command, - xy: [80, 24], detach: true, remain_on_exit: true, session_name: nil) + # @param session_name [String] + def initialize(session_name: nil) + @session_name = session_name || new_session_name + end + + # @param shell_command [String] + # @param xy [(Integer, Integer)] + # @param detach [Boolean] + # @param remain_on_exit [Boolean] useful if shell_command may unexpectedly + # fail quickly. In that case we can still capture the pane + # and read the error messages. + def new_session(shell_command, + xy: [80, 24], detach: true, remain_on_exit: true) @shell_command = shell_command @x, @y = xy @detach = detach - @session_name = session_name || new_session_name detach_args = @detach ? ["-d"] : [] - # "remain-on-exit" is useful if shell_command may unexpectedly fail quickly. - # In that case we can still capture the pane and read the error messages. remain_on_exit_args = if remain_on_exit ["set-hook", "-g", "session-created", "set remain-on-exit on", ";"] else [] end - system "tmux", + tmux_ret = system "tmux", * remain_on_exit_args, "new-session", "-s", @session_name, @@ -35,6 +45,11 @@ def initialize(shell_command, "-y", @y.to_s, * detach_args, "sh", "-c", shell_command + + return tmux_ret unless block_given? + + yield + ensure_no_session end def new_session_name @@ -91,3 +106,13 @@ def ensure_no_session kill_session if has_session? end end + +class YastTui < TmuxTui + def example(basename, &block) + basename += ".rb" unless basename.end_with? ".rb" + yast_ncurses = "#{__dir__}/yast_ncurses" + example_dir = "/usr/share/doc/packages/yast2-ycp-ui-bindings/examples" + + new_session("#{yast_ncurses} #{example_dir}/#{basename}", &block) + end +end diff --git a/tests/libyui/table_sort_spec.rb b/tests/libyui/table_sort_spec.rb index a7bbccbf..d10de2b7 100755 --- a/tests/libyui/table_sort_spec.rb +++ b/tests/libyui/table_sort_spec.rb @@ -5,9 +5,10 @@ around(:each) do |ex| yast_ncurses = "#{__dir__}/yast_ncurses" @base = "table_sort" - @tui = TmuxTui.new_session "#{yast_ncurses} #{__dir__}/#{@base}.rb change-current-item" - ex.run - @tui.ensure_no_session + @tui = TmuxTui.new + @tui.new_session "#{yast_ncurses} #{__dir__}/#{@base}.rb change-current-item" do + ex.run + end end bug = "1165388" # https://bugzilla.suse.com/show_bug.cgi?id=1165388