From 01d32004c852136df0b549477fd861334b10c838 Mon Sep 17 00:00:00 2001 From: admin Date: Tue, 10 Dec 2024 12:53:08 +0200 Subject: [PATCH] added locust --- app/extension/jira/extension_ui.py | 1 + app/jmeter/jira.jmx | 491 +++++++++++++++++------- app/locustio/jira/http_actions.py | 33 +- app/selenium_ui/jira/modules.py | 1 + app/selenium_ui/jira/pages/pages.py | 26 +- app/selenium_ui/jira/pages/selectors.py | 3 + 6 files changed, 406 insertions(+), 149 deletions(-) diff --git a/app/extension/jira/extension_ui.py b/app/extension/jira/extension_ui.py index 26e4b69aa..3ad126b68 100644 --- a/app/extension/jira/extension_ui.py +++ b/app/extension/jira/extension_ui.py @@ -25,6 +25,7 @@ def app_specific_action(webdriver, datasets): # login_page.go_to() # login_page.wait_for_login_page_loaded() # login_page.set_credentials(username=username, password=password) + # login_page.wait_for_dashboard_or_first_login_loaded() # if login_page.is_first_login(): # login_page.first_login_setup() # if login_page.is_first_login_second_page(): diff --git a/app/jmeter/jira.jmx b/app/jmeter/jira.jmx index 8a783bfb6..f16f52509 100644 --- a/app/jmeter/jira.jmx +++ b/app/jmeter/jira.jmx @@ -245,54 +245,11 @@ props.put("project_pages", String.valueOf(pages)); UTF-8 ${application.postfix}/login.jsp true - POST + GET true false - - - false - os_username - ${username} - = - true - - - false - os_password - ${password} - = - true - - - false - os_destination - - = - true - - - false - user_role - - = - true - - - false - atl_token - - = - true - - - true - login - Log In - = - true - - + @@ -329,6 +286,199 @@ props.put("project_pages", String.valueOf(pages)); + + + 200 + + + Assertion.response_code + false + 2 + + + + false + legacy_form + login-form-remember-me + $1$ + NOT_FOUND + 1 + all + + false + + + + groovy + + + true + String loginform = vars.get("legacy_form"); + +if ("NOT_FOUND".equals(loginform)) { + vars.put("legacy_login_form", "false"); + log.info("2sv flow detected"); +} else { + vars.put("legacy_login_form", "true"); + log.info("Legacy login flow detected"); +} + + + + + groovy + + + true + log.info("Legacy login flow: ${legacy_login_form}") + + + + + + ${__groovy(vars.get("legacy_login_form") == 'true')} + false + true + + + + Detected the start of a redirect chain + UTF-8 + ${application.postfix}/login.jsp + true + POST + true + false + + + + false + os_username + ${username} + = + true + + + false + os_password + ${password} + = + true + + + false + os_destination + + = + true + + + false + user_role + + = + true + + + false + atl_token + + = + true + + + true + login + Log In + = + true + + + + + + + + + Accept-Language + en-US,en;q=0.5 + + + Pragma + no-cache + + + Accept + text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 + + + Upgrade-Insecure-Requests + 1 + + + Content-Type + application/x-www-form-urlencoded + + + Cache-Control + no-cache + + + Accept-Encoding + gzip, deflate + + + + + + + + ${__groovy(vars.get("legacy_login_form") == 'false')} + false + true + + + + 2sv login flow + ${application.postfix}/rest/tsv/1.0/authenticate + POST + true + true + + + + false + {"username": "${username}", + "password": "${password}", + "rememberMe": "True", + "targetUrl": "" +} + = + + + + + + + + + Content-Type + application/json + + + + + + + 200 + + + Assertion.response_code + false + 2 + + + ${application.postfix}/ @@ -2005,7 +2155,7 @@ if ( sleep_time > 0 ) { false - + ${application.postfix}/browse/${issue_key} true GET @@ -2045,7 +2195,7 @@ if ( sleep_time > 0 ) { - + false x_issue_id id="key-val" rel="(\d+)" @@ -7115,104 +7265,159 @@ if ( sleep_time > 0 ) { - - Detected the start of a redirect chain - UTF-8 - ${application.postfix}/login.jsp - true - POST - true - false - - - - false - os_username - ${app_specific_username} - = - true - - - false - os_password - ${app_specific_password} - = - true - - - false - os_destination - - = - true - - - false - user_role - - = - true - - - false - atl_token - - = - true - - - true - login - Log In - = - true - - - - + + ${__groovy(vars.get("legacy_login_form") == 'true')} + false + true + - - - - Accept-Language - en-US,en;q=0.5 - - - Pragma - no-cache - - - Accept - text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 - - - Upgrade-Insecure-Requests - 1 - - - Content-Type - application/x-www-form-urlencoded - - - Cache-Control - no-cache - - - Accept-Encoding - gzip, deflate - - - - - - groovy - - - true - vars.put("run_as_specific_user", "true") + + Detected the start of a redirect chain + UTF-8 + ${application.postfix}/login.jsp + true + POST + true + false + + + + false + os_username + ${app_specific_username} + = + true + + + false + os_password + ${app_specific_password} + = + true + + + false + os_destination + + = + true + + + false + user_role + + = + true + + + false + atl_token + + = + true + + + true + login + Log In + = + true + + + + + + + + + Accept-Language + en-US,en;q=0.5 + + + Pragma + no-cache + + + Accept + text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 + + + Upgrade-Insecure-Requests + 1 + + + Content-Type + application/x-www-form-urlencoded + + + Cache-Control + no-cache + + + Accept-Encoding + gzip, deflate + + + + + + groovy + + + true + vars.put("run_as_specific_user", "true") prev.setIgnore() - - + + + + + + ${__groovy(vars.get("legacy_login_form") == 'false')} + false + true + + + + 2sv login flow + ${application.postfix}/rest/tsv/1.0/authenticate + POST + true + true + + + + false + {"username": "${app_specific_username}", + "password": "${app_specific_password}", + "rememberMe": "True", + "targetUrl": "" +} + = + + + + + + + + + Content-Type + application/json + + + + + + + 200 + + + Assertion.response_code + false + 2 + + + ${application.postfix}/rest/api/2/myself diff --git a/app/locustio/jira/http_actions.py b/app/locustio/jira/http_actions.py index ec5a3eb9e..3e6b02661 100644 --- a/app/locustio/jira/http_actions.py +++ b/app/locustio/jira/http_actions.py @@ -25,11 +25,38 @@ def login_and_view_dashboard(locust): body = params.login_body body['os_username'] = user[0] body['os_password'] = user[1] + legacy_form = False + + # Check if 2sv login form + r = locust.get('/login.jsp', catch_response=True) + if 'login-form-remember-me' in r.content: + legacy_form = True + # 100 /login.jsp - locust.post('/login.jsp', body, - TEXT_HEADERS, - catch_response=True) + if legacy_form: + locust.post('/login.jsp', body, + TEXT_HEADERS, + catch_response=True) + logger.locust_info(f"Legacy login flow for user {user[0]}") + else: + logger.locust_info(f"2SV login flow for user {user[0]}") + + login_body = {'username': user[0], + 'password': user[1], + 'rememberMe': 'True', + 'targetUrl': '' + } + + headers = { + "Content-Type": "application/json" + } + + # 15 /rest/tsv/1.0/authenticate + locust.post('/rest/tsv/1.0/authenticate', + json=login_body, + headers=headers, + catch_response=True) r = locust.get('/', catch_response=True) if not r.content: diff --git a/app/selenium_ui/jira/modules.py b/app/selenium_ui/jira/modules.py index 091553a85..04e462d23 100644 --- a/app/selenium_ui/jira/modules.py +++ b/app/selenium_ui/jira/modules.py @@ -79,6 +79,7 @@ def sub_measure(): login_page.set_credentials( username=datasets['current_session']['username'], password=datasets['current_session']['password']) + login_page.wait_for_dashboard_or_first_login_loaded() if login_page.is_first_login(): login_page.first_login_setup() if login_page.is_first_login_second_page(): diff --git a/app/selenium_ui/jira/pages/pages.py b/app/selenium_ui/jira/pages/pages.py index e38bcf51e..197a11c0b 100644 --- a/app/selenium_ui/jira/pages/pages.py +++ b/app/selenium_ui/jira/pages/pages.py @@ -20,6 +20,10 @@ class Login(BasePage): page_loaded_selector = LoginPageLocators.system_dashboard base_url = UrlManager().host + def __init__(self, driver): + super().__init__(driver) + self.is_2sv_login = False + def is_first_login(self): return True if self.get_elements(LoginPageLocators.continue_button) else False @@ -28,6 +32,10 @@ def wait_for_login_page_loaded(self): # Jira 10.0.1 has issue when clicking too fast on login button resulting in user is not logged in. from time import sleep sleep(1) + if not self.get_elements(LoginPageLocators.login_submit_button): + self.is_2sv_login = True + print("INFO: 2sv login form") + def is_first_login_second_page(self): return True if self.get_elements(LoginPageLocators.avatar_page_next_button) else False @@ -44,9 +52,21 @@ def first_login_second_page_setup(self): self.wait_until_visible(DashboardLocators.dashboard_window) def set_credentials(self, username, password): - self.get_element(LoginPageLocators.login_field).send_keys(username) - self.get_element(LoginPageLocators.password_field).send_keys(password) - self.get_element(LoginPageLocators.login_submit_button).click() + login_field = LoginPageLocators.login_field + password_field = LoginPageLocators.password_field + submit_button = LoginPageLocators.login_submit_button + if self.is_2sv_login: + login_field = LoginPageLocators.login_field_2sv + password_field = LoginPageLocators.password_field_2sv + submit_button = LoginPageLocators.login_submit_button_2sv + + self.wait_until_visible(login_field).send_keys(username) + self.wait_until_visible(password_field).send_keys(password) + self.wait_until_visible(submit_button).click() + + def wait_for_dashboard_or_first_login_loaded(self): + self.wait_until_any_ec_presented((LoginPageLocators.system_dashboard, + LoginPageLocators.continue_button)) def __get_footer_text(self): return self.get_element(LoginPageLocators.footer).text diff --git a/app/selenium_ui/jira/pages/selectors.py b/app/selenium_ui/jira/pages/selectors.py index 43f75557c..d59b4ee26 100644 --- a/app/selenium_ui/jira/pages/selectors.py +++ b/app/selenium_ui/jira/pages/selectors.py @@ -79,6 +79,9 @@ class LoginPageLocators: login_field = (By.ID, 'login-form-username') password_field = (By.ID, 'login-form-password') login_submit_button = (By.ID, 'login-form-submit') + login_field_2sv = (By.ID, 'username-field') + password_field_2sv = (By.ID, 'password-field') + login_submit_button_2sv = (By.ID, 'login-button') system_dashboard = (By.ID, "dashboard") footer = (By.ID, 'footer-build-information')