libyui_client 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +15 -0
  3. data/.rspec +3 -0
  4. data/.rubocop.yml +41 -0
  5. data/.travis.yml +11 -0
  6. data/Gemfile +8 -0
  7. data/LICENSE.txt +21 -0
  8. data/README.md +210 -0
  9. data/Rakefile +20 -0
  10. data/bin/console +15 -0
  11. data/bin/setup +8 -0
  12. data/lib/libyui_client.rb +42 -0
  13. data/lib/libyui_client/actions.rb +12 -0
  14. data/lib/libyui_client/app.rb +230 -0
  15. data/lib/libyui_client/error.rb +13 -0
  16. data/lib/libyui_client/filter_extractor.rb +28 -0
  17. data/lib/libyui_client/http/http_client.rb +36 -0
  18. data/lib/libyui_client/http/response.rb +21 -0
  19. data/lib/libyui_client/http/version_controller.rb +26 -0
  20. data/lib/libyui_client/http/widget_controller.rb +54 -0
  21. data/lib/libyui_client/local_process.rb +73 -0
  22. data/lib/libyui_client/logger.rb +32 -0
  23. data/lib/libyui_client/timer.rb +20 -0
  24. data/lib/libyui_client/version.rb +6 -0
  25. data/lib/libyui_client/wait.rb +21 -0
  26. data/lib/libyui_client/waitable.rb +39 -0
  27. data/lib/libyui_client/widgets.rb +30 -0
  28. data/lib/libyui_client/widgets/bargraph.rb +62 -0
  29. data/lib/libyui_client/widgets/base.rb +114 -0
  30. data/lib/libyui_client/widgets/button.rb +33 -0
  31. data/lib/libyui_client/widgets/checkbox.rb +53 -0
  32. data/lib/libyui_client/widgets/combobox.rb +95 -0
  33. data/lib/libyui_client/widgets/datefield.rb +47 -0
  34. data/lib/libyui_client/widgets/label.rb +41 -0
  35. data/lib/libyui_client/widgets/menubutton.rb +48 -0
  36. data/lib/libyui_client/widgets/multilinebox.rb +84 -0
  37. data/lib/libyui_client/widgets/numberbox.rb +76 -0
  38. data/lib/libyui_client/widgets/progressbar.rb +45 -0
  39. data/lib/libyui_client/widgets/radiobutton.rb +35 -0
  40. data/lib/libyui_client/widgets/richtext.rb +36 -0
  41. data/lib/libyui_client/widgets/selectionbox.rb +87 -0
  42. data/lib/libyui_client/widgets/tab.rb +81 -0
  43. data/lib/libyui_client/widgets/table.rb +154 -0
  44. data/lib/libyui_client/widgets/textbox.rb +94 -0
  45. data/lib/libyui_client/widgets/timefield.rb +45 -0
  46. data/lib/libyui_client/widgets/tree.rb +149 -0
  47. data/libyui_client.gemspec +44 -0
  48. metadata +135 -0
@@ -0,0 +1,114 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LibyuiClient
4
+ module Widgets
5
+ class Base
6
+ include Waitable
7
+
8
+ def initialize(widget_controller, filter)
9
+ @widget_controller = widget_controller
10
+ @filter = filter
11
+ end
12
+
13
+ # Allows to check if widget exists on the current screen or not.
14
+ # Can be called against any widget.
15
+ # @return [Boolean] true if widget exists, false otherwise.
16
+ # @example Check if button with id 'test' exists
17
+ # app.button(id: 'test').exists? # true
18
+ def exists?
19
+ LibyuiClient.logger.info("Checking if #{class_name} with #{@filter} exists")
20
+ find_widgets
21
+ LibyuiClient.logger.info("#{class_name} exists: #{@filter}")
22
+ true
23
+ rescue Error::WidgetNotFoundError
24
+ LibyuiClient.logger.info("#{class_name} does not exist: #{@filter}")
25
+ false
26
+ end
27
+
28
+ # Allows to check if widget enabled or disabled.
29
+ # Can be called against any widget. Widget that does not have "enabled" property is counted as enabled.
30
+ # @return [Boolean] true if widget enabled, false otherwise.
31
+ # @example Check if button with id 'test' enabled
32
+ # app.button(id: 'test').enabled? # true
33
+ def enabled?
34
+ enabled_prop = property(:enabled)
35
+ enabled_prop.nil? || enabled_prop == true
36
+ end
37
+
38
+ # Returns debug_label value for widget.
39
+ # Can be called against any widget.
40
+ # @return [String] value of debug_label property
41
+ # @example Get debug_label value for button
42
+ # {
43
+ # "class": "YQWizardButton",
44
+ # "debug_label": "Cancel",
45
+ # "fkey": 9,
46
+ # "id": "cancel",
47
+ # "label": "&Cancel"
48
+ # }
49
+ # @example
50
+ # debug_label = app.button(id: 'cancel').debug_label # Cancel
51
+ def debug_label
52
+ property(:debug_label)
53
+ end
54
+
55
+ # Returns value of widget property.
56
+ # This method can be used to retrieve value of some specific property,
57
+ # but widget does not have a method to return the value.
58
+ # Can be called against any widget.
59
+ # @param property [Symbol] symbolic name of the property to get value for.
60
+ # @return [Object] value for property of a widget
61
+ # @example Get value of "label" property for button with id "test"
62
+ # value = app.button(id: 'test').property(:label)
63
+ def property(property)
64
+ LibyuiClient.logger.info("Get #{property} for #{class_name} #{@filter}")
65
+ result = find_widgets.first[property.to_sym]
66
+ LibyuiClient.logger.info("Found '#{property}=#{result}' for #{class_name} #{@filter}")
67
+ result
68
+ end
69
+
70
+ # This method can be used to send any action to widget.
71
+ # Can be called against any widget.
72
+ # @param params [Hash] actions to be sent (e.g. action: 'press').
73
+ # @example Send action 'press' to button widget.
74
+ # app.button(id: 'test').action(action: 'press')
75
+ def action(params)
76
+ unless @filter.regex.empty?
77
+ widget = find_widgets.first
78
+ @filter = FilterExtractor.new(widget)
79
+ end
80
+ LibyuiClient.logger.info("Send #{params} action for #{class_name} #{@filter}")
81
+ @widget_controller.send_action(@filter.plain, params)
82
+ end
83
+
84
+ # Get all widgets found with filter.
85
+ # The method is mainly introduced for "class" filter, which can return an array of widgets.
86
+ # It only makes sense to use this method whenever server side filters allow to find individually those
87
+ # collected widgets, otherwise those will not be able to access their internal properties.
88
+ # @return [Array] array of deserialized widgets.
89
+ # Then actions that are specified for the widget can be called while iterating over the returned array.
90
+ # @example Get all checkboxes and check all of them
91
+ # checkboxes = app.checkbox(class: "YCheckBox").collect_all
92
+ # checkboxes.each{ |checkbox| puts checkbox.check }
93
+ def collect_all
94
+ LibyuiClient.logger.info("Collect all #{class_name} widgets with filter #{@filter}")
95
+ widgets = find_widgets
96
+ LibyuiClient.logger.info("Found widgets for filter #{@filter}: #{widgets}")
97
+ widgets.map do |widget|
98
+ self.class.new(@widget_controller, FilterExtractor.new(widget))
99
+ end
100
+ end
101
+
102
+ private
103
+
104
+ def class_name
105
+ self.class.name.split('::').last
106
+ end
107
+
108
+ def find_widgets
109
+ LibyuiClient.logger.info("Search for #{class_name} #{@filter}")
110
+ @widget_controller.find(@filter.plain).body(regex_filter: @filter.regex)
111
+ end
112
+ end
113
+ end
114
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LibyuiClient
4
+ module Widgets
5
+ # Class representing a button in UI. It can be YQWizardButton, YPushButton.
6
+ class Button < Widgets::Base
7
+ # Sends action to click the button in UI.
8
+ # @return [Button] in case action is successful
9
+ # @example Click button with id 'test'
10
+ # app.button(id: 'test').click
11
+ def click
12
+ action(action: Actions::PRESS)
13
+ self
14
+ end
15
+
16
+ # Returns fkey value for the button.
17
+ # @return [Integer] F (function) key that can be used as shortcut to press the button.
18
+ # @example Get fkey value for YQWizardButton
19
+ # {
20
+ # "class": "YQWizardButton",
21
+ # "debug_label": "Cancel",
22
+ # "fkey": 9,
23
+ # "id": "cancel",
24
+ # "label": "&Cancel"
25
+ # }
26
+ # @example
27
+ # fkey = app.button(id: 'cancel').fkey
28
+ def fkey
29
+ property(:fkey)
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LibyuiClient
4
+ module Widgets
5
+ # Class representing a Checkbox in UI. It can be YCheckBox or YCheckBoxFrame.
6
+ class Checkbox < Widgets::Base
7
+ # Sends action to explicitly check the checkbox in UI (regardless of the current state).
8
+ # @return [Checkbox] in case action is successful
9
+ # @example Check checkbox with id 'test'
10
+ # app.checkbox(id: 'test').check
11
+ def check
12
+ action(action: Actions::CHECK)
13
+ self
14
+ end
15
+
16
+ # Returns the state of checkbox (checked/unchecked).
17
+ # Gets value from 'value' parameter in JSON representation of YCheckBox or YCheckBoxFrame.
18
+ # @return [Boolean] true if it is checked, false otherwise.
19
+ # @example Get checkbox state
20
+ # {
21
+ # "class": "YCheckBox",
22
+ # "debug_label": "Change the Time Now",
23
+ # "id": "change_now",
24
+ # "label": "Chan&ge the Time Now",
25
+ # "notify": true,
26
+ # "value": true
27
+ # }
28
+ # @example
29
+ # app.checkbox(id: 'change_now').checked? # true
30
+ def checked?
31
+ property(:value)
32
+ end
33
+
34
+ # Sends action to toggle the checkbox in UI (i.e. uncheck when checked, or check otherwise).
35
+ # @return [Checkbox] in case action is successful
36
+ # @example Toggle checkbox with id 'test'
37
+ # app.checkbox(id: 'test').toggle
38
+ def toggle
39
+ action(action: Actions::TOGGLE)
40
+ self
41
+ end
42
+
43
+ # Sends action to explicitly uncheck the checkbox in UI (regardless of the current state).
44
+ # @return [Checkbox] in case action is successful
45
+ # @example Uncheck checkbox with id 'test'
46
+ # checkbox(id: 'test').uncheck
47
+ def uncheck
48
+ action(action: Actions::UNCHECK)
49
+ self
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,95 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LibyuiClient
4
+ module Widgets
5
+ # Class representing a ComboBox in the UI. It can be YComboBox.
6
+ class Combobox < Widgets::Base
7
+ # Returns the list of items available to select from combobox.
8
+ # @return [Array<String>] array of strings.
9
+ # @example Get items from combobox with id "nfs_version"
10
+ # {
11
+ # "class": "YComboBox",
12
+ # "debug_label": "NFS Version",
13
+ # "icon_base_path": "",
14
+ # "id": "nfs_version",
15
+ # "items": [
16
+ # {
17
+ # "label": "Any (Highest Available)",
18
+ # "selected": true
19
+ # },
20
+ # {
21
+ # "label": "Force NFSv3"
22
+ # }
23
+ # ],
24
+ # "items_count": 5,
25
+ # "label": "NFS &Version",
26
+ # "value": "Any (Highest Available)"
27
+ # }
28
+ # @example
29
+ # app.combobox(id: 'nfs_version').items
30
+ # # Any (Highest Available)
31
+ # # Force NFSv3
32
+ def items
33
+ property(:items).map { |x| x[:label] }
34
+ end
35
+
36
+ # Sends action to select the item in combobox.
37
+ # @param item [String] item to select in combobox.
38
+ # List of items can be retrieved from JSON "items"->"label" manually or by using 'combobox(filter).items'.
39
+ # @return [Combobox] in case action is successful
40
+ # @raise LibyuiClient::Error::ItemNotFoundInWidgetError in case value is not found in combobox.
41
+ # @example Select "Force NFSv3" item in combobox with id "nfs_version"
42
+ # app.combobox(id: 'nfs_version').select('Force NFSv3')
43
+ def select(item)
44
+ action(action: Actions::SELECT, value: item)
45
+ self
46
+ end
47
+
48
+ # Returns selected item in combobox.
49
+ # @example Get selected item in combobox with id "nfs_version"
50
+ # {
51
+ # "class": "YComboBox",
52
+ # "debug_label": "NFS Version",
53
+ # "icon_base_path": "",
54
+ # "id": "nfs_version",
55
+ # "items": [
56
+ # {
57
+ # "label": "Any (Highest Available)",
58
+ # "selected": true
59
+ # },
60
+ # {
61
+ # "label": "Force NFSv3"
62
+ # }
63
+ # ],
64
+ # "items_count": 5,
65
+ # "label": "NFS &Version",
66
+ # "value": "Any (Highest Available)"
67
+ # }
68
+ # @example
69
+ # app.combobox(id: 'nfs_version').value
70
+ def value
71
+ property(:value)
72
+ end
73
+
74
+ # Sends action to set string to the editable combobox.
75
+ # @param item [String] value to set in the combobox.
76
+ # To check if combobox is editable, call editable?
77
+ # @return [Combobox] in case action is successful
78
+ # @raise LibyuiClient::Error::ItemNotFoundInWidgetError in case value is not found in combobox.
79
+ # @example Set "Custom Version" item in combobox with id "nfs_version"
80
+ # app.combobox(id: 'nfs_version').select('Custom Version')
81
+ def set(value)
82
+ action(action: Actions::ENTER_TEXT, value: value)
83
+ self
84
+ end
85
+
86
+ # Allows to check if combobox is editable and allows setting .
87
+ # @return [Boolean] true if widget enabled, false otherwise.
88
+ # @example Check if combobox with id 'test' editable
89
+ # app.combobox(id: 'test').editable? # true
90
+ def editable?
91
+ property(:editable) == true
92
+ end
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LibyuiClient
4
+ module Widgets
5
+ # Class representing a date field in the UI, namely YDateField.
6
+ class Datefield < Widgets::Base
7
+ # Sends action to set the value of date field. Accepts Date, Time or DateTime
8
+ # object and sets value in ISO 8601 format YYYY-MM-DD.
9
+ # @param date [Date] date to be set in date field
10
+ # @return [Datefield] in case action is successful
11
+ # @raise LibyuiClientError if parameter is not Date, DateTime or Time
12
+ # @example Set date in date field with id 'test' to current date
13
+ # app.datefield(id: 'date').set(Time.now)
14
+ # @example Set date in date field with id 'test' to 2002-12-29
15
+ # app.datefield(id: 'date').set(DateTime.new(2002,12,29))
16
+ # @example Set date in date field with id 'test' to 2021-02-03
17
+ # app.datefield(id: 'date').set(Date.new(2001,2,3))
18
+ def set(date)
19
+ unless [Date, DateTime, Time].any? { |c| date.is_a? c }
20
+ raise Error::LibyuiClientError, 'Parameter is not Date, Time or DateTime'
21
+ end
22
+
23
+ action(action: Actions::ENTER_TEXT, value: date.strftime('%F'))
24
+ self
25
+ end
26
+
27
+ # Returns text that is currently set for datefield.
28
+ # Gets value from 'value' parameter in JSON representation of YDateField.
29
+ # @return [String] value
30
+ # @example Get value from datefield with id "date"
31
+ # {
32
+ # "class" : "YDateField",
33
+ # "debug_label" : "Date:",
34
+ # "hstretch" : true,
35
+ # "id" : "date",
36
+ # "label" : "&Date:",
37
+ # "notify" : true,
38
+ # "value" : "1989-11-09"
39
+ # }
40
+ # @example
41
+ # app.datefield(id: 'date').value # '1989-11-09'
42
+ def value
43
+ property(:value)
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LibyuiClient
4
+ module Widgets
5
+ # Class representing a Label UI. It can be YLabel, YLabel_Heading
6
+ class Label < Widgets::Base
7
+ # Returns if label is a heading being represented in bold in the UI
8
+ # Gets value from 'is_heading' parameter in JSON representation of YLabel_Heading.
9
+ # @return [Boolean] true if it is a heading, false otherwise.
10
+ # @example Check label with 'label' "Product name"
11
+ # {
12
+ # "class": "YLabel_Heading",
13
+ # "debug_label": "Product name ...",
14
+ # "is_heading": true,
15
+ # "label": "Product name",
16
+ # "text": "Product name"
17
+ # }
18
+ # @example
19
+ # app.label(label: 'Product name').heading? # true
20
+ def heading?
21
+ heading_prop = property(:is_heading)
22
+ !heading_prop.nil? && heading_prop == true
23
+ end
24
+
25
+ # Returns text value for the label.
26
+ # @return [String] value
27
+ # @example Get text value for YLabel, YLabelHeading
28
+ # {
29
+ # "class": "YLabel",
30
+ # "debug_label": "short message",
31
+ # "label": "test label",
32
+ # "text": "text label"
33
+ # }
34
+ # @example
35
+ # text = app.label(label: 'test label').text # "text label"
36
+ def text
37
+ property(:text)
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LibyuiClient
4
+ module Widgets
5
+ # Class representing a menubutton in UI. It can be YMenuButton.
6
+ class Menubutton < Widgets::Base
7
+ # Sends action to click on one of the items of the menubutton in UI.
8
+ # @param item [String] value to select from items.
9
+ # @example Click button with label 'test_button' for menubutton with id 'test_id'.
10
+ # @example
11
+ # app.menubutton(id: 'test_id').click('test_button')
12
+ def click(item)
13
+ action(action: Actions::PRESS, value: item)
14
+ end
15
+
16
+ # Returns the list of items available to select from widget.
17
+ # @return [Array<String>] array of strings.
18
+ # @example Get items from widget with id "test_id"
19
+ # {
20
+ # "class": "YMenuButton",
21
+ # "debug_label": "test",
22
+ # "icon_base_path": "",
23
+ # "id": "test_id",
24
+ # "items": [
25
+ # {
26
+ # "label": "button1"
27
+ # },
28
+ # {
29
+ # "label": "button2"
30
+ # },
31
+ # {
32
+ # "label": "button3"
33
+ # }
34
+ # ],
35
+ # "items_count": 3,
36
+ # "label": "button group"
37
+ # }
38
+ # @example
39
+ # app.menubutton(id: 'test').items
40
+ # # button1
41
+ # # button2
42
+ # # button3
43
+ def items
44
+ property(:items).map { |x| x[:label] }
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,84 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LibyuiClient
4
+ module Widgets
5
+ # Class representing a multilinebox in the UI. It can be YMultiLineEdit.
6
+ class Multilinebox < Widgets::Base
7
+ # Returns maximum string length to set in the multilinebox
8
+ # @return [Integer] maximum number of character to set in the multilinebox
9
+ # @example Check maximum string length in multilinebox with id 'TEST_ID'
10
+ # }
11
+ # "class" : "YMultiLineEdit",
12
+ # "debug_label" : "test_label",
13
+ # "default_visible_lines" : 3,
14
+ # "hstretch" : true,
15
+ # "hweight" : 1,
16
+ # "id" : "\"TEST_ID\"",
17
+ # "input_max_length" : -1,
18
+ # "label" : "test_label",
19
+ # "value" : "",
20
+ # "vstretch" : true
21
+ # }
22
+ # @example
23
+ # app.multilinebox(id: '"TEST_ID"').max_length
24
+ # # -1
25
+ def max_length
26
+ property(:input_max_length)
27
+ end
28
+
29
+ # Returns the default visible number of lines for the multilinebox
30
+ # @return [Integer] default number of visible lines for the multilinebox
31
+ # @example Check the default visible number of line for multilinebox with id 'TEST_ID'
32
+ # }
33
+ # "class" : "YMultiLineEdit",
34
+ # "debug_label" : "test_label",
35
+ # "default_visible_lines" : 3,
36
+ # "hstretch" : true,
37
+ # "hweight" : 1,
38
+ # "id" : "\"TEST_ID\"",
39
+ # "input_max_length" : -1,
40
+ # "label" : "test_label",
41
+ # "value" : "",
42
+ # "vstretch" : true
43
+ # }
44
+ # @example
45
+ # app.multilinebox(id: '"TEST_ID"').visible_lines
46
+ # # 3
47
+ def visible_lines
48
+ property(:default_visible_lines)
49
+ end
50
+
51
+ # Sends action to set the value of multilinebox.
52
+ # @param value [String] text to be set in multilinebox
53
+ # @return [Multilinebox] in case action is successful
54
+ # @example Set text in multilinebox with id 'TEST_ID' to 'text'
55
+ # app.multilinebox(id: '"TEST_ID"').set("text\ntext in new line")
56
+ def set(value)
57
+ action(action: Actions::ENTER_TEXT, value: value)
58
+ self
59
+ end
60
+
61
+ # Returns text that is currently set for multilinebox.
62
+ # Gets value from 'value' parameter in JSON representation of YMultiLineEdit.
63
+ # @return [String] text set as value in the multilinebox.
64
+ # @example Get value from multilinebox with id "address"
65
+ # }
66
+ # "class" : "YMultiLineEdit",
67
+ # "debug_label" : "test_label",
68
+ # "default_visible_lines" : 3,
69
+ # "hstretch" : true,
70
+ # "hweight" : 1,
71
+ # "id" : "\"TEST_ID\"",
72
+ # "input_max_length" : -1,
73
+ # "label" : "test_label",
74
+ # "value" : "This is a \nmultiline\ntext",
75
+ # "vstretch" : true
76
+ # }
77
+ # @example
78
+ # app.multilinebox(id: '"TEST_ID"').value # This is a \nmultiline\ntext
79
+ def value
80
+ property(:value)
81
+ end
82
+ end
83
+ end
84
+ end