Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

jsm/confluence/bump-versions #1663

Merged
merged 2 commits into from
Jan 20, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ This repository contains Taurus scripts for performance testing of Atlassian Dat
* Jira [Long Term Support release](https://confluence.atlassian.com/enterprise/atlassian-enterprise-releases-948227420.html): `9.12.17` and `10.3.0`

* Supported Jira Service Management versions:
* Jira Service Management [Long Term Support release](https://confluence.atlassian.com/enterprise/atlassian-enterprise-releases-948227420.html): `5.12.12` and `10.3.1`
* Jira Service Management [Long Term Support release](https://confluence.atlassian.com/enterprise/atlassian-enterprise-releases-948227420.html): `5.12.17` and `10.3.1`

* Supported Confluence versions:
* Confluence [Long Term Support release](https://confluence.atlassian.com/enterprise/atlassian-enterprise-releases-948227420.html): `8.5.14` and `9.2.0`
* Confluence [Long Term Support release](https://confluence.atlassian.com/enterprise/atlassian-enterprise-releases-948227420.html): `8.5.18` and `9.2.0`

* Supported Bitbucket Server versions:
* Bitbucket Server [Long Term Support release](https://confluence.atlassian.com/enterprise/atlassian-enterprise-releases-948227420.html): `8.19.14` and `9.4.1`
Expand Down
240 changes: 195 additions & 45 deletions app/jmeter/jsm_agents.jmx

Large diffs are not rendered by default.

166 changes: 146 additions & 20 deletions app/jmeter/jsm_customers.jmx
Original file line number Diff line number Diff line change
Expand Up @@ -249,33 +249,18 @@ import org.apache.commons.io.FileUtils;
<boolProp name="TransactionController.includeTimers">false</boolProp>
</TransactionController>
<hashTree>
<HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="100 /servicedesk/customer/user/login" enabled="true">
<stringProp name="HTTPSampler.path">${application.postfix}/servicedesk/customer/user/login</stringProp>
<HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="100 /servicedesk/customer/user/login">
<stringProp name="HTTPSampler.path">${application.postfix}/login.jsp</stringProp>
<boolProp name="HTTPSampler.follow_redirects">true</boolProp>
<stringProp name="HTTPSampler.method">POST</stringProp>
<stringProp name="HTTPSampler.method">GET</stringProp>
<boolProp name="HTTPSampler.use_keepalive">true</boolProp>
<boolProp name="HTTPSampler.postBodyRaw">false</boolProp>
<elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="User Defined Variables">
<collectionProp name="Arguments.arguments">
<elementProp name="os_password" elementType="HTTPArgument">
<boolProp name="HTTPArgument.always_encode">true</boolProp>
<stringProp name="Argument.name">os_password</stringProp>
<stringProp name="Argument.value">${password}</stringProp>
<stringProp name="Argument.metadata">=</stringProp>
<boolProp name="HTTPArgument.use_equals">true</boolProp>
</elementProp>
<elementProp name="os_username" elementType="HTTPArgument">
<boolProp name="HTTPArgument.always_encode">true</boolProp>
<stringProp name="Argument.name">os_username</stringProp>
<stringProp name="Argument.value">${username}</stringProp>
<stringProp name="Argument.metadata">=</stringProp>
<boolProp name="HTTPArgument.use_equals">true</boolProp>
</elementProp>
</collectionProp>
<collectionProp name="Arguments.arguments"/>
</elementProp>
</HTTPSamplerProxy>
<hashTree>
<HeaderManager guiclass="HeaderPanel" testclass="HeaderManager" testname="HTTP Header manager">
<HeaderManager guiclass="HeaderPanel" testclass="HeaderManager" testname="HTTP Header manager" enabled="true">
<collectionProp name="HeaderManager.headers">
<elementProp name="Accept" elementType="Header">
<stringProp name="Header.name">Accept</stringProp>
Expand All @@ -296,6 +281,147 @@ import org.apache.commons.io.FileUtils;
</collectionProp>
</HeaderManager>
<hashTree/>
<RegexExtractor guiclass="RegexExtractorGui" testclass="RegexExtractor" testname="legacy login form check" enabled="true">
<stringProp name="RegexExtractor.useHeaders">false</stringProp>
<stringProp name="RegexExtractor.refname">legacy_form</stringProp>
<stringProp name="RegexExtractor.regex">login-form-remember-me</stringProp>
<stringProp name="RegexExtractor.template">$1$</stringProp>
<stringProp name="RegexExtractor.default">NOT_FOUND</stringProp>
<stringProp name="RegexExtractor.match_number">1</stringProp>
<stringProp name="Sample.scope">all</stringProp>
<stringProp name="Scope.variable"></stringProp>
<boolProp name="RegexExtractor.default_empty_value">false</boolProp>
</RegexExtractor>
<hashTree/>
<JSR223PostProcessor guiclass="TestBeanGUI" testclass="JSR223PostProcessor" testname="set legacy form type" enabled="true">
<stringProp name="scriptLanguage">groovy</stringProp>
<stringProp name="parameters"></stringProp>
<stringProp name="filename"></stringProp>
<stringProp name="cacheKey">true</stringProp>
<stringProp name="script">String loginform = vars.get(&quot;legacy_form&quot;);

if (&quot;NOT_FOUND&quot;.equals(loginform)) {
vars.put(&quot;legacy_login_form&quot;, &quot;false&quot;);
log.info(&quot;2sv flow detected&quot;);
} else {
vars.put(&quot;legacy_login_form&quot;, &quot;true&quot;);
log.info(&quot;Legacy login flow detected&quot;);
}
</stringProp>
</JSR223PostProcessor>
<hashTree/>
<JSR223PostProcessor guiclass="TestBeanGUI" testclass="JSR223PostProcessor" testname="Logger" enabled="true">
<stringProp name="scriptLanguage">groovy</stringProp>
<stringProp name="parameters"></stringProp>
<stringProp name="filename"></stringProp>
<stringProp name="cacheKey">true</stringProp>
<stringProp name="script">log.info(&quot;Legacy login flow: ${legacy_login_form}&quot;)
</stringProp>
</JSR223PostProcessor>
<hashTree/>
</hashTree>
<IfController guiclass="IfControllerPanel" testclass="IfController" testname="If legacy login flow" enabled="true">
<stringProp name="IfController.condition">${__groovy(vars.get(&quot;legacy_login_form&quot;) == &apos;true&apos;)}</stringProp>
<boolProp name="IfController.evaluateAll">false</boolProp>
<boolProp name="IfController.useExpression">true</boolProp>
</IfController>
<hashTree>
<HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="100 /servicedesk/customer/user/login" enabled="true">
<stringProp name="HTTPSampler.path">${application.postfix}/servicedesk/customer/user/login</stringProp>
<boolProp name="HTTPSampler.follow_redirects">true</boolProp>
<stringProp name="HTTPSampler.method">POST</stringProp>
<boolProp name="HTTPSampler.use_keepalive">true</boolProp>
<boolProp name="HTTPSampler.postBodyRaw">false</boolProp>
<elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="User Defined Variables">
<collectionProp name="Arguments.arguments">
<elementProp name="os_password" elementType="HTTPArgument">
<boolProp name="HTTPArgument.always_encode">true</boolProp>
<stringProp name="Argument.name">os_password</stringProp>
<stringProp name="Argument.value">${password}</stringProp>
<stringProp name="Argument.metadata">=</stringProp>
<boolProp name="HTTPArgument.use_equals">true</boolProp>
</elementProp>
<elementProp name="os_username" elementType="HTTPArgument">
<boolProp name="HTTPArgument.always_encode">true</boolProp>
<stringProp name="Argument.name">os_username</stringProp>
<stringProp name="Argument.value">${username}</stringProp>
<stringProp name="Argument.metadata">=</stringProp>
<boolProp name="HTTPArgument.use_equals">true</boolProp>
</elementProp>
</collectionProp>
</elementProp>
</HTTPSamplerProxy>
<hashTree>
<HeaderManager guiclass="HeaderPanel" testclass="HeaderManager" testname="HTTP Header manager" enabled="true">
<collectionProp name="HeaderManager.headers">
<elementProp name="Accept" elementType="Header">
<stringProp name="Header.name">Accept</stringProp>
<stringProp name="Header.value">*/*</stringProp>
</elementProp>
<elementProp name="X-Requested-With" elementType="Header">
<stringProp name="Header.name">X-Requested-With</stringProp>
<stringProp name="Header.value">XMLHttpRequest</stringProp>
</elementProp>
<elementProp name="Content-Type" elementType="Header">
<stringProp name="Header.name">Content-Type</stringProp>
<stringProp name="Header.value">application/x-www-form-urlencoded</stringProp>
</elementProp>
<elementProp name="" elementType="Header">
<stringProp name="Header.name">X-Atlassian-Token</stringProp>
<stringProp name="Header.value">no-check</stringProp>
</elementProp>
</collectionProp>
</HeaderManager>
<hashTree/>
</hashTree>
</hashTree>
<IfController guiclass="IfControllerPanel" testclass="IfController" testname="if 2sv login flow" enabled="true">
<stringProp name="IfController.condition">${__groovy(vars.get(&quot;legacy_login_form&quot;) == &apos;false&apos;)}</stringProp>
<boolProp name="IfController.evaluateAll">false</boolProp>
<boolProp name="IfController.useExpression">true</boolProp>
</IfController>
<hashTree>
<HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="15 /rest/tsv/1.0/authenticate" enabled="true">
<stringProp name="TestPlan.comments">2sv login flow</stringProp>
<stringProp name="HTTPSampler.path">${application.postfix}/rest/tsv/1.0/authenticate</stringProp>
<stringProp name="HTTPSampler.method">POST</stringProp>
<boolProp name="HTTPSampler.use_keepalive">true</boolProp>
<boolProp name="HTTPSampler.postBodyRaw">true</boolProp>
<elementProp name="HTTPsampler.Arguments" elementType="Arguments">
<collectionProp name="Arguments.arguments">
<elementProp name="" elementType="HTTPArgument">
<boolProp name="HTTPArgument.always_encode">false</boolProp>
<stringProp name="Argument.value">{&quot;username&quot;: &quot;${username}&quot;,&#xd;
&quot;password&quot;: &quot;${password}&quot;,&#xd;
&quot;rememberMe&quot;: &quot;True&quot;,&#xd;
&quot;targetUrl&quot;: &quot;&quot;&#xd;
}</stringProp>
<stringProp name="Argument.metadata">=</stringProp>
</elementProp>
</collectionProp>
</elementProp>
</HTTPSamplerProxy>
<hashTree>
<HeaderManager guiclass="HeaderPanel" testclass="HeaderManager" testname="HTTP Header Manager" enabled="true">
<collectionProp name="HeaderManager.headers">
<elementProp name="Content-Type" elementType="Header">
<stringProp name="Header.name">Content-Type</stringProp>
<stringProp name="Header.value">application/json</stringProp>
</elementProp>
</collectionProp>
</HeaderManager>
<hashTree/>
<ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Response Assertion" enabled="true">
<collectionProp name="Asserion.test_strings">
<stringProp name="49586">200</stringProp>
</collectionProp>
<stringProp name="Assertion.custom_message"></stringProp>
<stringProp name="Assertion.test_field">Assertion.response_code</stringProp>
<boolProp name="Assertion.assume_success">false</boolProp>
<intProp name="Assertion.test_type">2</intProp>
</ResponseAssertion>
<hashTree/>
</hashTree>
</hashTree>
<HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="105 /servicedesk/customer/portals" enabled="true">
<stringProp name="HTTPSampler.path">${application.postfix}/servicedesk/customer/portals</stringProp>
Expand Down
30 changes: 29 additions & 1 deletion app/locustio/jsm/agents/agents_http_actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,35 @@ def agent_login_and_view_dashboard(locust, jsm_agent_dataset):
body['os_username'] = user[0]
body['os_password'] = user[1]

locust.post('/login.jsp', body, TEXT_HEADERS, catch_response=True)
legacy_form = False

# is 2sv login form
r = locust.get('/login.jsp', catch_response=True)
if b'login-form-remember-me' in r.content:
legacy_form = 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:
raise Exception('Please check server hostname in jsm.yml file')
Expand Down
65 changes: 52 additions & 13 deletions app/locustio/jsm/customers/customers_http_actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,22 +47,61 @@ def customer_login_and_view_portals(locust):
locust.session_data_storage['username'] = user[0]
locust.session_data_storage['password'] = user[1]

r = locust.post(
'/servicedesk/customer/user/login',
body,
headers=JSM_CUSTOMERS_HEADERS,
catch_response=True)
legacy_form = False

locust.get('/servicedesk/customer/portals', catch_response=True)
# is 2sv login form
r = locust.get('/login.jsp', catch_response=True)
if b'login-form-remember-me' in r.content:
legacy_form = True

locust.post(
'/rest/servicedesk/1/customer/models',
json=params.resources_body.get("115"),
headers=RESOURCE_HEADERS,
catch_response=True)
if legacy_form:
r = locust.post(
'/servicedesk/customer/user/login',
body,
headers=JSM_CUSTOMERS_HEADERS,
catch_response=True)

locust.get('/servicedesk/customer/portals', catch_response=True)

locust.post(
'/rest/servicedesk/1/customer/models',
json=params.resources_body.get("115"),
headers=RESOURCE_HEADERS,
catch_response=True)

assert '"loginSucceeded":true' in r.content.decode('utf-8'), 'Customer login is failed'

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",
"Accept": "*/*"
}

locust.post('/rest/tsv/1.0/authenticate?os_authType=none',
json=login_body,
headers=headers,
catch_response=True)

locust.get('/servicedesk/customer/portals', catch_response=True)

locust.post(
'/rest/servicedesk/1/customer/models',
json=params.resources_body.get("115"),
headers=RESOURCE_HEADERS,
catch_response=True)

assert '"loginSucceeded":true' in r.content.decode(
'utf-8'), 'Customer login is failed'
r = locust.get('/', catch_response=True)
if not r.content:
raise Exception('Please check server hostname in jsm.yml file')
r.content.decode('utf-8')


@jsm_customer_measure('locust_customer_view_portal')
Expand Down
1 change: 1 addition & 0 deletions app/selenium_ui/jsm/modules_agents.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ def measure():
@print_timing("selenium_agent_login:open_login_page")
def sub_measure():
login_page.go_to()
login_page.is_2sv()
sub_measure()

@print_timing("selenium_agent_login:login_and_view_dashboard")
Expand Down
2 changes: 1 addition & 1 deletion app/selenium_ui/jsm/modules_customers.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,11 @@ def measure():
@print_timing("selenium_customer_login:open_login_page")
def sub_measure():
login_page.go_to()
login_page.is_2sv()
webdriver.app_version = login_page.get_app_version()
if login_page.is_logged_in():
login_page.delete_all_cookies()
login_page.go_to()
login_page.wait_for_page_loaded()
sub_measure()

@print_timing("selenium_customer_login:login_and_view_portal")
Expand Down
27 changes: 24 additions & 3 deletions app/selenium_ui/jsm/pages/agent_pages.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,18 @@ class Login(BasePage):
base_url = UrlManager().host
page_loaded_selector = LoginPageLocators.system_dashboard

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

def is_2sv(self):
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

Expand All @@ -37,9 +46,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
Expand Down
Loading