From 8c23b7b68d58d084e239d436eb7786dc52616b9d Mon Sep 17 00:00:00 2001 From: Alvaro Laserna Date: Tue, 20 Sep 2022 16:40:31 +0200 Subject: [PATCH 1/7] adding not selenium/appium descriptions --- README.md | 53 +++++++++++++++++++ .../tests/cases/case_before_after_case.yaml | 47 ++++++++++++++++ lib/core/case_runner.rb | 4 +- 3 files changed, 102 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e3d51957..bdbbc179 100644 --- a/README.md +++ b/README.md @@ -714,11 +714,64 @@ You can access any var throgout the code by using the wrapper `$AND_CLI_*$`, in ### write_file + +This type is meant for writing files: + + - Type: write_file + Role: role1 (Optional. if not specified will use the first one defined in the case Roles) + Value: Specific Value Text + Name: name_of_the_file.txt # default is name.txt + Folder: /Path/To/Folder # default is project directory `.` + + ### get_timestamp + +This type retrieves de UTC timestamp when it is executed, and you can write it in a specific file or to specific variable: + + - Type: get_timestamp + Role: role1 (Optional. if not specified will use the first one defined in the case Roles) + Format: Date_Format -> DDMMYY -> check https://www.ibm.com/docs/en/zos/2.4.0?topic=functions-strftime-convert-formatted-time + File: name_of_the_file.txt # relative or full path to the file to write the date (Use when Var is not used) + Var: Variable_Name -> Variable to set with the current timestamp (Use when File is not used) + ### set_env_var + +This type sets a Variable to a specific value. + + - Type: set_env_var + Role: role1 (Optional. if not specified will use the first one defined in the case Roles) + Value: Value + Var: Variable_Name + ### sleep + +This type stops the execution for the amount of time specifyied for the role that is written. + + - Type: sleep + Role: role1 (Optional. if not specified will use the first one defined in the case Roles) + Time: 10 + ### assert +There are different types of asserts that you can perform with testray and the variables. + + - Type: assert + Role: command1 + Asserts: + - Type: contain/n_contain/eq/ne/le/gt/ge + Var: TEST_VAR_NUMBERS + Value: 8 + +
+contain: "Var" value contains the value within "Value"
+n_contain: "Var" value does NOT contain the value within "Value"
+eq: "Var" value is equal to the value within "Value"
+ne: "Var" value is NOT equal to the value within "Value"
+le: "Var" value is lower or equal to the value within "Value"
+gt: "Var" value is greater than the value within "Value"
+ge: "Var" value is greater or equal to the value within "Value"
+
+ ### operation There are a lot of operations, look at https://github.com/project-eutopia/keisan diff --git a/examples/tests/cases/case_before_after_case.yaml b/examples/tests/cases/case_before_after_case.yaml index 3a4a135f..e6834bb0 100644 --- a/examples/tests/cases/case_before_after_case.yaml +++ b/examples/tests/cases/case_before_after_case.yaml @@ -18,6 +18,23 @@ TestBeforeCaseError: Role: command1 Value: echo $VAR_1 +TestAfterCaseDoubleError: + ParallelRoles: true + Roles: + - Role: desktopChrome + App: desktop + - Role: command1 + App: command + Vars: + TEST_VAR: "var_greater" + TEST_VAR_NUMBERS: 5 + Aftercases: + - DesktopCaseError2 + Actions: + - Type: case + Value: DesktopCaseError + Role: $AND_CLI_MAINROLE$ + # HELPER CASES DesktopPreCaseError: @@ -30,6 +47,10 @@ DesktopPreCaseError: Role: $AND_CLI_MAINROLE$ DesktopCaseError: + Roles: + - Role: desktopChrome + App: desktop + Step: case with an error ParallelRoles: true Actions: - Type: navigate @@ -51,6 +72,32 @@ DesktopCaseError: Value: DesktopCaseError Role: $AND_CLI_MAINROLE$ +DesktopCaseError2: + Roles: + - Role: desktopChrome + App: desktop + Step: case with an error + ParallelRoles: true + Actions: + - Type: navigate + Role: desktopChrome + Value: http://google.com + - Type: click + Role: desktopChrome + Condition: + - Value: 3 + Operation: visible + Result: true + Raise: true + Strategy: id + CheckTime: 5 + Id: false_id_2 + - Type: sleep + Time: 2 + - Type: case + Value: DesktopCaseError + Role: $AND_CLI_MAINROLE$ + AfterCase: Actions: - Type: navigate diff --git a/lib/core/case_runner.rb b/lib/core/case_runner.rb index c03baa10..87d1889a 100644 --- a/lib/core/case_runner.rb +++ b/lib/core/case_runner.rb @@ -56,8 +56,8 @@ def run(case_name, parent_params = {}) steps["Aftercases"].each do |after_case| begin run(convert_value(after_case)) - rescue => e - log_warn("After Case '#{after_case}' Error: #{e.message}") + rescue => e_after + log_warn("After Case '#{after_case}' Error: #{e_after.message}") end end end From fc446a0760c385ce3002a31154f5564dccc2b94b Mon Sep 17 00:00:00 2001 From: Alvaro Laserna Date: Wed, 21 Sep 2022 09:51:35 +0200 Subject: [PATCH 2/7] adding Only browser readme types --- README.md | 106 ++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 91 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index bdbbc179..11c9de78 100644 --- a/README.md +++ b/README.md @@ -459,17 +459,17 @@ You can also set different Strategies and Ids as in the `click` Type. Greps expl - Type: get_attribute Strategy: id/css/xpath/uiautomator/class_chain/predicate Id: //div[contains(text(), "http")] - Condition: - - Value: 3 - Operation: visible - Result: true - Greps: - - var: SOME_VAR - attr: value (Mandatory) - condition: nempty (Optional) - remove: google.com/ (Optional) - match: "google.com(.*)" - NoRaise: false/true (Default - false -> will rise error on fail) + Condition: + - Value: 3 + Operation: visible + Result: true + Greps: + - var: SOME_VAR + attr: value (Mandatory) + condition: nempty (Optional) + remove: google.com/ (Optional) + match: "google.com(.*)" + NoRaise: false/true (Default - false -> will rise error on fail) You can also set different Strategies and Ids as in the `click` Type. Greps explained in `command` Type and Condition explained in [Conditions](#condition) Section. @@ -523,18 +523,73 @@ You can also set different Strategies and Ids as in the `click` Type. Greps expl NoRaise: false/true (Default - false -> will rise error on fail) ### switch_window + +Switches to the provided window index. + + - Type: switch_window + Role: role1 (Optional. if not specified will use the first one defined in the case Roles) + Value: 2 # (It is a number, and it will check if that window number exists) + CheckTime: 10 # (For how long it will check that the windows exist) + ### switch_frame + - Type: switch_frame + Role: role1 (Optional. if not specified will use the first one defined in the case Roles) Strategy: css (Only if Value isn't declared) Id: "[name='iFrameName']" (Only if Value isn't declared) Value: Iframe_ID (Only if Strategy and Id aren't declared) ### maximize + +Maximizes the current window. + + - Type: maximize + Role: role1 (Optional. if not specified will use the first one defined in the case Roles) + Width: 1000 (Optional) + Height: 1000 (Optional) + ### minimize + +Minimizes the current window. + + - Type: minimize + Role: role1 (Optional. if not specified will use the first one defined in the case Roles) + ### submit + +It only works with forms on web pages, so make sure to point to the form element + + - Type: submit + Role: role1 (Optional. if not specified will use the first one defined in the case Roles) + Strategy: id/css/xpath/uiautomator/class_chain/... + Id: //some/path + Condition: + - Value: 5 (Time in seconds) + Operation: visible + Result: true + NoRaise: false/true (Default - false -> will rise error on fail) + ### click_js +It is a different way to click on an element, but it uses Javascript interface. + + - Type: click_js + Role: role1 (Optional. if not specified will use the first one defined in the case Roles) + Strategy: id/css/xpath/uiautomator/class_chain/... + Id: //some/path + Condition: + - Value: 5 (Time in seconds) + Operation: visible + Result: true + NoRaise: false/true (Default - false -> will rise error on fail) + ### add_cookie +It adds a cookie to the current browser. + + - Type: add_cookie + Role: role1 (Optional. if not specified will use the first one defined in the case Roles) + Name: cookie_name + Value: Value ## Only Mobile @@ -567,10 +622,10 @@ Closes the app and leaves it running in the background. - Type: start_record Bitrate: 3000000 (Recording Bitrate - optional - Android) - Resolution: 1200x900 (Optional - Android) - FPS: 30 (Optional - iOS) - Video_Type: h264 (Optional - iOS) - Video_Quality: medium (Optional - iOS) + Resolution: 1200x900 (Optional - Android) + FPS: 30 (Optional - iOS) + Video_Type: h264 (Optional - iOS) + Video_Quality: medium (Optional - iOS) Role: role1 Time: "180" (Timeout - optional) @@ -638,9 +693,30 @@ It works simillar as click, but it holds the pressing. The labels and options th if `X` and `Y` are not provided then middle of the screen is clicked. ### clipboard + +Gets the clipboard value from the device and assigns it to some Var using Greps. + + - Type: clipboard + Role: role1 (Optional. if not specified will use the first one defined in the case Roles) + Greps: + - var: SOME_VAR + condition: nempty (Optional) + remove: google.com/ (Optional) + match: "google.com(.*)" + ### notifications + +Opens notifications var (Only Android) + + - Type: notifications + Role: role1 (Optional. if not specified will use the first one defined in the case Roles) + ### back +Works as pressing the button `back` on the phone to go to the previous screen. + + - Type: back + Role: role1 (Optional. if not specified will use the first one defined in the case Roles) ## API From 2b3fa1651ead5d5252dd7baa9bd3c8e6bc58c69d Mon Sep 17 00:00:00 2001 From: Alvaro Laserna Date: Wed, 21 Sep 2022 09:54:47 +0200 Subject: [PATCH 3/7] fix indentation --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 11c9de78..b47173c0 100644 --- a/README.md +++ b/README.md @@ -526,14 +526,14 @@ You can also set different Strategies and Ids as in the `click` Type. Greps expl Switches to the provided window index. - - Type: switch_window + - Type: switch_window Role: role1 (Optional. if not specified will use the first one defined in the case Roles) Value: 2 # (It is a number, and it will check if that window number exists) CheckTime: 10 # (For how long it will check that the windows exist) ### switch_frame - - Type: switch_frame + - Type: switch_frame Role: role1 (Optional. if not specified will use the first one defined in the case Roles) Strategy: css (Only if Value isn't declared) Id: "[name='iFrameName']" (Only if Value isn't declared) @@ -543,7 +543,7 @@ Switches to the provided window index. Maximizes the current window. - - Type: maximize + - Type: maximize Role: role1 (Optional. if not specified will use the first one defined in the case Roles) Width: 1000 (Optional) Height: 1000 (Optional) @@ -552,7 +552,7 @@ Maximizes the current window. Minimizes the current window. - - Type: minimize + - Type: minimize Role: role1 (Optional. if not specified will use the first one defined in the case Roles) ### submit From c5b433862baa0402275ec851c7f7b718b1828bae Mon Sep 17 00:00:00 2001 From: Alvaro Laserna Date: Wed, 21 Sep 2022 09:57:38 +0200 Subject: [PATCH 4/7] fix indent --- README.md | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index b47173c0..51ac933b 100644 --- a/README.md +++ b/README.md @@ -527,33 +527,33 @@ You can also set different Strategies and Ids as in the `click` Type. Greps expl Switches to the provided window index. - Type: switch_window - Role: role1 (Optional. if not specified will use the first one defined in the case Roles) - Value: 2 # (It is a number, and it will check if that window number exists) - CheckTime: 10 # (For how long it will check that the windows exist) + Role: role1 (Optional. if not specified will use the first one defined in the case Roles) + Value: 2 # (It is a number, and it will check if that window number exists) + CheckTime: 10 # (For how long it will check that the windows exist) ### switch_frame - Type: switch_frame - Role: role1 (Optional. if not specified will use the first one defined in the case Roles) - Strategy: css (Only if Value isn't declared) - Id: "[name='iFrameName']" (Only if Value isn't declared) - Value: Iframe_ID (Only if Strategy and Id aren't declared) + Role: role1 (Optional. if not specified will use the first one defined in the case Roles) + Strategy: css (Only if Value isn't declared) + Id: "[name='iFrameName']" (Only if Value isn't declared) + Value: Iframe_ID (Only if Strategy and Id aren't declared) ### maximize Maximizes the current window. - Type: maximize - Role: role1 (Optional. if not specified will use the first one defined in the case Roles) - Width: 1000 (Optional) - Height: 1000 (Optional) + Role: role1 (Optional. if not specified will use the first one defined in the case Roles) + Width: 1000 (Optional) + Height: 1000 (Optional) ### minimize Minimizes the current window. - Type: minimize - Role: role1 (Optional. if not specified will use the first one defined in the case Roles) + Role: role1 (Optional. if not specified will use the first one defined in the case Roles) ### submit @@ -595,7 +595,7 @@ It adds a cookie to the current browser. ### set_orientation (Mobile) - - Type: set_orientation + - Type: set_orientation Role: role1 Value: landscape/portrait @@ -603,18 +603,18 @@ It adds a cookie to the current browser. Closes the app and leaves it running in the background. - - Type: close_app + - Type: close_app Role: role1 ### launch_app (Mobile) - - Type: launch_app + - Type: launch_app Role: role1 Value: com.android.vending (Optional - Android app package / iOS bundle ID) ### terminate_app - - Type: terminate_app + - Type: terminate_app Role: role1 Value: com.apple.Preferences (Optional - Android app package / iOS bundle ID) @@ -622,10 +622,10 @@ Closes the app and leaves it running in the background. - Type: start_record Bitrate: 3000000 (Recording Bitrate - optional - Android) - Resolution: 1200x900 (Optional - Android) - FPS: 30 (Optional - iOS) - Video_Type: h264 (Optional - iOS) - Video_Quality: medium (Optional - iOS) + Resolution: 1200x900 (Optional - Android) + FPS: 30 (Optional - iOS) + Video_Type: h264 (Optional - iOS) + Video_Quality: medium (Optional - iOS) Role: role1 Time: "180" (Timeout - optional) From 3704e4aae5618ed9b316652ef12c0c286e13f5c0 Mon Sep 17 00:00:00 2001 From: Alvaro Laserna Date: Wed, 21 Sep 2022 09:59:21 +0200 Subject: [PATCH 5/7] last indent fixes --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 51ac933b..adc39d76 100644 --- a/README.md +++ b/README.md @@ -796,8 +796,8 @@ This type is meant for writing files: - Type: write_file Role: role1 (Optional. if not specified will use the first one defined in the case Roles) Value: Specific Value Text - Name: name_of_the_file.txt # default is name.txt - Folder: /Path/To/Folder # default is project directory `.` + Name: name_of_the_file.txt # default is name.txt + Folder: /Path/To/Folder # default is project directory `.` ### get_timestamp @@ -807,8 +807,8 @@ This type retrieves de UTC timestamp when it is executed, and you can write it i - Type: get_timestamp Role: role1 (Optional. if not specified will use the first one defined in the case Roles) Format: Date_Format -> DDMMYY -> check https://www.ibm.com/docs/en/zos/2.4.0?topic=functions-strftime-convert-formatted-time - File: name_of_the_file.txt # relative or full path to the file to write the date (Use when Var is not used) - Var: Variable_Name -> Variable to set with the current timestamp (Use when File is not used) + File: name_of_the_file.txt # relative or full path to the file to write the date (Use when Var is not used) + Var: Variable_Name -> Variable to set with the current timestamp (Use when File is not used) ### set_env_var @@ -817,7 +817,7 @@ This type sets a Variable to a specific value. - Type: set_env_var Role: role1 (Optional. if not specified will use the first one defined in the case Roles) Value: Value - Var: Variable_Name + Var: Variable_Name ### sleep From 5c0bd30795a5cae9876a95c7e1fcb4b03414fd9e Mon Sep 17 00:00:00 2001 From: Alvaro Laserna Date: Thu, 22 Sep 2022 09:00:52 +0200 Subject: [PATCH 6/7] end adding all the types --- README.md | 87 +++++++++++++++++++++++++++++++++++++++++++++- lib/core/device.rb | 4 +-- 2 files changed, 88 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index adc39d76..6dd01719 100644 --- a/README.md +++ b/README.md @@ -480,18 +480,103 @@ You can also set different Strategies and Ids as in the `click` Type. Greps expl Value: context ### get_current_context + + - Type: get_current_context + Role: role1 (Optional. if not specified will use the first one defined in the case Roles) + Greps: + - var: SOME_VAR + attr: value (Mandatory) + condition: nempty (Optional) + remove: "" (Optional) + match: "(.*)" + ### get_contexts + +Prints all the available contexts + + - Type: get_contexts + Role: role1 (Optional. if not specified will use the first one defined in the case Roles) + ### get_source + +Gets the page source from the web or mobile app and writes it in `./page_source.xml` + + - Type: get_source + Role: role1 (Optional. if not specified will use the first one defined in the case Roles) + ### set_network + + - Type: set_network + Role: role1 (Optional. if not specified will use the first one defined in the case Roles) + Condition: {offline: false, latency: 5, download_throughput: 2000, upload_throughput: 2000} + ### scroll_to + +It uses JavaScript to do the scroll within a webpage by using the injection of this method: `arguments[0].scrollIntoView(#{options});`. For it to work, you need to specify an element, and there is an optional `Options` value, which will default to `true`. + + - Type: scroll_to + Role: role1 (Optional. if not specified will use the first one defined in the case Roles) + Strategy: id/css/xpath/uiautomator/class_chain/predicate + Id: //div[contains(text(), "http")] + Options: true (optional) + + ### screenshot +Takes a screenshot of the Role device in use. You can specify to take screenshots in an interval, for a specific period of time (Optional). You can specify wether to use the same file name or use timestamps `Overwrite`. + + - Type: screenshot + Role: role1 (Optional. if not specified will use the first one defined in the case Roles) + Interval: + For: 10 + Every: 1 + Overwrite: False + ### wait_for_attribute + + - Type: wait_for_attribute + Role: role1 (Optional. if not specified will use the first one defined in the case Roles) + Strategy: id/css/xpath/uiautomator/class_chain/predicate + Id: //div[contains(text(), "http")] + Attribute: Name + Value: Some_Name + + ### visible_for -### visible_for_not_raise + + - Type: visible_for + Role: role1 (Optional. if not specified will use the first one defined in the case Roles) + Strategy: id/css/xpath/uiautomator/class_chain/predicate + Id: //div[contains(text(), "http")] + Time: 10 + ### wait_for_page_to_load + + - Type: wait_for_page_to_load + Role: role1 (Optional. if not specified will use the first one defined in the case Roles) + Time: 10 + ### collection_visible_for + + - Type: collection_visible_for + Role: role1 (Optional. if not specified will use the first one defined in the case Roles) + Elements: + - Strategy: id/css/xpath/uiautomator/class_chain/predicate + Id: //div[contains(text(), "http")] + Time: 10 + - Strategy: id/css/xpath/uiautomator/class_chain/predicate + Id: //div[contains(text(), "http")] + Time: 10 + ### wait_not_visible +Waits until the element specified is not visible. + + - Type: wait_not_visible + Role: role1 (Optional. if not specified will use the first one defined in the case Roles) + Strategy: id/css/xpath/uiautomator/class_chain/predicate + Id: //div[contains(text(), "http")] + Time: 10 + ## Only Browser ### clear_field diff --git a/lib/core/device.rb b/lib/core/device.rb index e54d4752..c7da1457 100644 --- a/lib/core/device.rb +++ b/lib/core/device.rb @@ -1199,11 +1199,11 @@ def visible_for_not_raise(action) # Accepts: # Time - def collection_visible_for(collection) + def collection_visible_for(action) time = (action["Time"] ? action["Time"] : @timeout) start = Time.now while (Time.now - start) < time - collection.each do |element| + action["Elements"].each do |element| element["Time"] = 0.2 self.wait_for(element) end From 4ff6c3e92f1d110dea76dab3eb7986561ce4e944 Mon Sep 17 00:00:00 2001 From: Alvaro Laserna Date: Thu, 22 Sep 2022 16:05:40 +0200 Subject: [PATCH 7/7] fix conditions formating --- README.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 6dd01719..e4e29a30 100644 --- a/README.md +++ b/README.md @@ -953,13 +953,13 @@ Operation examples: ### Conditions - - Type: wait_for/click/send_keys/press/... Anything that calls an element by `Strategy:Id` labels - Strategy: id/css/xpath/uiautomator/class_chain/predicate - Id: //div[contains(text(), "http")] - Condition: - - Value: 5 # Time in seconds for the condition to fullfil (or not) - Result: true/false # If you expect the condition to be true or false - Operation: visible/eq/neq/visible_for - Raise: true/false # If you want the condition to raise an error + - Type: wait_for/click/send_keys/press/... Anything that calls an element by `Strategy:Id` labels + Strategy: id/css/xpath/uiautomator/class_chain/predicate + Id: //div[contains(text(), "http")] + Condition: + - Value: 5 # Time in seconds for the condition to fullfil (or not) + Result: true/false # If you expect the condition to be true or false + Operation: visible/eq/neq/visible_for + Raise: true/false # If you want the condition to raise an error