Skip to content

Commit

Permalink
Support for "submit totp" precrawl action (#322)
Browse files Browse the repository at this point in the history
* Updates for upporting submit_otp precrawl action; doc updates;
bumped up version

Signed-off-by: Saurabh Sinha <sinha108@gmail.com>

* Fix keybert version issue and related test failure

Signed-off-by: Saurabh Sinha <sinha108@gmail.com>

* Updated doc

Signed-off-by: Saurabh Sinha <sinha108@gmail.com>

Signed-off-by: Saurabh Sinha <sinha108@gmail.com>
  • Loading branch information
sinha108 committed Jan 25, 2023
1 parent d0f4138 commit d71183d
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 28 deletions.
53 changes: 43 additions & 10 deletions doc/ui/tkltest_ui_config_options.md
Original file line number Diff line number Diff line change
Expand Up @@ -272,16 +272,31 @@ Selenium API tests to be executed as one-time setup before test execution begins
The form data specification is provided in TOML format in a particular schema.
For an example specification, see the [pre-crawl actions spec for the Petclinic webapp](../../test/ui/data/petclinic/tkltest_ui_precrawl_actions_config.toml).

The specification consists of a sequence of "click" (link, button) and "enter" (into text box) actions;
currently, these are the only supported pre-crawl actions. A pre-crawl action has the following
properties:

1. `action_type`: the type of action to perform (click or enter)
2. one of the following element locator properties: `by_id`, `by_name`, `under_xpath`, `with_text`, `by_css_selector`
3. if `action_type` is "enter", the property `input_value` specifying the value to be entered in text box

The following sample illustrates a sequence of five pre-crawl actions: three click actions, followed by a
form-field enter action, and finally another click action.
The specification consists of a sequence of "click" (link, button) and "enter" (into text box) actions
and two specialized actions: one for accepting alert dialogs and another for generating and submitting
time-based one-time passwords (TOTP). Currently, these four are the only supported pre-crawl actions.

A pre-crawl action can have the following properties:

1. `action_type`: the type of action to perform (`click`, `enter`, `alert_accept`, `submit_totp`)
2. if `action_type` is `enter` or `click`, one of the following element locator properties: `by_id`, `by_name`, `under_xpath`, `with_text`, `by_css_selector`
3. if `action_type` is `enter`, one of the following properties:
- `input_value` specifying the value to be entered in text box or
- `input_value_env_var` specifying the name of an environment variable containing the value to be entered
(use this property for specifying passwords/secrets required, e.g., for authentication before crawling starts)
4. if `action_type` is `submit_totp`, the following properties may be specified:
- `totp_secret_env_var` specifying the name of an environment variable containing the secret to be used for TOTP generation
(if omitted, a secret code is created by default for OTP generation)
- `max_attempts` specifying the maximum number of attempts to be made for TOTP submission
- nested table `[precrawl_action.enter]` containing an element locator property (as described in item 2) for the TOTP textbox
- nested table `[precrawl_action.click]` containing an element locator property (as described in item 2) for the TOTP submit button
5. A pre-crawl action can be tagged as optional by adding the property `optional=true` (by default, an action is not
optional). For an optional pre-crawl action, if the execution of the action fails, the tool ignores the failure
and moves on to the next pre-crawl action. For a non-optional (i.e., mandatory) pre-crawl action failure, test generation
terminates.

The following sample illustrates a sequence of seven pre-crawl actions: three `click` actions, an `alert_accept` action, an
`enter` action, two `click` actions, and finally a `submit_totp` action.

```
[[precrawl_action]]
Expand All @@ -296,6 +311,9 @@ form-field enter action, and finally another click action.
action_type = "click"
under_xpath = "//*[@id=\"primary-links\"]/li"
[[precrawl_action]]
action_type = alert_accept
[[precrawl_action]]
action_type = "enter"
by_name = "fileName"
Expand All @@ -304,4 +322,19 @@ form-field enter action, and finally another click action.
[[precrawl_action]]
action_type = "click"
with_text = "Upload file"
[[precrawl_action]]
action_type = "click"
by_id = "totp"
optional = true
[[precrawl_action]]
action_type = "submit_totp"
totp_secret_env_var = "TKLTESTUI_TOTP_SECRET"
optional = true
max_attempts = 2
[precrawl_action.enter]
by_id = "totp_input"
[precrawl_action.click]
by_id = "submit"
```
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ def run(self):
'pyenchant==3.2.2',
'lxml==4.9.1',
'xmltodict==0.12.0',
'keybert==0.4.0',
'keybert==0.7.0',
'pandas==1.4.3'

],
Expand Down
8 changes: 4 additions & 4 deletions test/ui/heuristic_labels_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ def test_heuristic_labels(self):
with open(os.path.join(self.helper_file_dir, 'crawl_paths_petclinic_small.json')) as file2:
crawl_paths_petclinic = json.load(file2)

correct_labels = [{2: ['on page "Address book", click "post login"',
correct_labels = [{2: ['on page "Address book", click "login"',
['on page "Address book", enter "user: admin"',
'on page "Address book", enter "password: secret"'], []],
3: ['on page "Address book", click "next birthdays"',
Expand Down Expand Up @@ -53,17 +53,17 @@ def test_heuristic_labels(self):
'on page "Address book", select "group: cEyhmIaV"',
'on page "Address book", select "to_group: cEyhmIaV"'], ['number of results']]},
{2: ['on page "SpringPetclinicAngular", click "veterinarians"', [], []],
3: ['on page "SpringPetclinicAngular", click "owner add"', [], []]}]
3: ['on page "SpringPetclinicAngular", click "brand"', [], []]}]

correct_method_labels = [
{
'2_3': 'This test navigates the path: click "post login".\n\t* Then it enters values in form "number of results" and submits the form.\n\t* The unique clickables in this path are: on page "Address book", click "post login", on page "Address book", click "next birthdays".',
'2_3': 'This test navigates the path: click "login".\n\t* Then it enters values in form "number of results" and submits the form.\n\t* The unique clickables in this path are: on page "Address book", click "login", on page "Address book", click "next birthdays".',
'4_5': 'This test enters values in form "number of results".\n\t* Then it navigates the path: click "export", click "groups".\n\t* The unique clickables in this path are: on page "Address book", click "export", on page "Address book ([none])", click "groups".',
'6_7': 'This test enters values in form "number of results".\n\t* Then it navigates the path: click "print all", click "v8.0.0 - r475".\n\t* The unique clickables in this path are: on page "Address book", click "print all", on page "Address book (cEyhmIaV)", click "v8.0.0 - r475".',
'9_11': 'This test enters values in form "number of results".\n\t* Then it navigates the path: click "import", click "v8.0.0 - r475".\n\t* The unique clickables in this path are: on page "Address book", click "import", on page "Address book ([none])", click "v8.0.0 - r475".',
'12': 'This test enters values in form "number of results".\n\t* Then it navigates the path: click "print phones".\n\t* The unique clickables in this path are: on page "Address book", click "print phones".'},
{
'2_3': 'This test navigates the path: click "veterinarians", click "owner add".\n\t* The unique clickables in this path are: on page "SpringPetclinicAngular", click "veterinarians", on page "SpringPetclinicAngular", click "owner add".'}]
'2_3': 'This test navigates the path: click "veterinarians", click "brand".\n\t* The unique clickables in this path are: on page "SpringPetclinicAngular", click "veterinarians", on page "SpringPetclinicAngular", click "brand".'}]

# check for all DOM fragments in these two files, that labels are produced correctly

Expand Down
2 changes: 1 addition & 1 deletion tkltest/_version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = '2.4.0'
__version__ = '2.4.2'
31 changes: 19 additions & 12 deletions tkltest/ui/generate/generate.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,22 +60,29 @@ def process_generate_command(config):

# print message about generated crwaljax API tests
test_class_file = os.path.join(output_crawl_dir, CRAWLJAX_API_TEST_FILE)
test_count = __get_generated_test_count(test_class_file=test_class_file)
try:
test_count = __get_generated_test_count(test_class_file=test_class_file)
except FileNotFoundError:
tkltest_status('Test generation terminated without creating any tests')
browser_util.cleanup_browser_instances(browser)
sys.exit(0)

tkltest_status('Generated {} Crawljax API test cases; written to test class file "{}"'
.format(test_count, test_class_file))

# generate Selenium API tests
tkltest_status('Creating Selenium API test cases from crawl paths')
try:
generate_selenium.generate_selenium_api_tests(config=config, crawl_dir=output_crawl_dir)
test_class_file = os.path.join(output_crawl_dir, SELENIUM_API_TEST_FILE)
test_count = __get_generated_test_count(test_class_file=test_class_file)
tkltest_status('Generated {} Selenium API test cases; written to test class file "{}"'
.format(test_count, test_class_file))
except Exception as e:
tkltest_status('Exception occurred while creating Selenium API tests: {}'.format(str(e)), error=True)
browser_util.cleanup_browser_instances(browser)
sys.exit(1)
if test_count > 0:
tkltest_status('Creating Selenium API test cases from crawl paths')
try:
generate_selenium.generate_selenium_api_tests(config=config, crawl_dir=output_crawl_dir)
test_class_file = os.path.join(output_crawl_dir, SELENIUM_API_TEST_FILE)
test_count = __get_generated_test_count(test_class_file=test_class_file)
tkltest_status('Generated {} Selenium API test cases; written to test class file "{}"'
.format(test_count, test_class_file))
except Exception as e:
tkltest_status('Exception occurred while creating Selenium API tests: {}'.format(str(e)), error=True)
browser_util.cleanup_browser_instances(browser)
sys.exit(1)

# cleanup browser instances
browser_util.cleanup_browser_instances(browser)
Expand Down

0 comments on commit d71183d

Please sign in to comment.