diff --git a/custom-vu/src/main/kotlin/jces1209/vu/JiraCloudScenario.kt b/custom-vu/src/main/kotlin/jces1209/vu/JiraCloudScenario.kt index e1a76fe..f168761 100644 --- a/custom-vu/src/main/kotlin/jces1209/vu/JiraCloudScenario.kt +++ b/custom-vu/src/main/kotlin/jces1209/vu/JiraCloudScenario.kt @@ -53,11 +53,6 @@ class JiraCloudScenario : Scenario { projectMemory = similarities.projectMemory, createIssueButtons = listOf(By.id("createGlobalItem"), By.id("createGlobalItemIconButton")) ), - searchWithJql = SearchCloudFilter( - jira = jira, - meter = meter, - filters = similarities.filtersMemory - ), browseProjects = BrowseCloudProjects( jira = jira, meter = meter, @@ -75,12 +70,8 @@ class JiraCloudScenario : Scenario { projectKeyMemory = similarities.projectMemory, browseProjectPage = CloudProjectNavigatorPage(jira.driver) ), - customizeColumns = CustomizeColumns( - jira = jira, - meter = meter, - columnsEditor = CloudColumnsEditor(jira.driver) - ), issueNavigator = CloudIssueNavigator(jira.driver), + columnsEditor = CloudColumnsEditor(jira.driver), topBar = CloudTopBar(jira.driver) ) } diff --git a/custom-vu/src/main/kotlin/jces1209/vu/JiraDcScenario.kt b/custom-vu/src/main/kotlin/jces1209/vu/JiraDcScenario.kt index 467e0bd..4159a5d 100644 --- a/custom-vu/src/main/kotlin/jces1209/vu/JiraDcScenario.kt +++ b/custom-vu/src/main/kotlin/jces1209/vu/JiraDcScenario.kt @@ -8,10 +8,9 @@ import com.atlassian.performance.tools.jiraactions.api.measure.ActionMeter import com.atlassian.performance.tools.jiraactions.api.memories.UserMemory import com.atlassian.performance.tools.jiraactions.api.scenario.JiraCoreScenario import com.atlassian.performance.tools.jiraactions.api.scenario.Scenario +import jces1209.vu.action.BrowseProjectIssues import jces1209.vu.action.CreateAnIssue -import jces1209.vu.action.CustomizeColumns -import jces1209.vu.action.SearchServerFilter -import jces1209.vu.action.* +import jces1209.vu.action.WorkOnDashboard import jces1209.vu.page.DcIssueNavigator import jces1209.vu.page.DcIssuePage import jces1209.vu.page.bars.topBar.dc.DcTopBar @@ -55,11 +54,6 @@ class JiraDcScenario : Scenario { projectMemory = similarities.projectMemory, createIssueButtons = listOf(By.id("create_link")) ), - searchWithJql = SearchServerFilter( - jira = jira, - meter = meter, - filters = similarities.filtersMemory - ), browseProjects = BrowseProjectsAction( jira = jira, meter = meter, @@ -77,12 +71,8 @@ class JiraDcScenario : Scenario { projectKeyMemory = similarities.projectMemory, browseProjectPage = DcProjectNavigatorPage(jira.driver) ), - customizeColumns = CustomizeColumns( - jira = jira, - meter = meter, - columnsEditor = DcColumnsEditor(jira.driver) - ), issueNavigator = DcIssueNavigator(jira.driver), + columnsEditor = DcColumnsEditor(jira.driver), topBar = DcTopBar(jira.driver) ) } diff --git a/custom-vu/src/main/kotlin/jces1209/vu/MeasureType.kt b/custom-vu/src/main/kotlin/jces1209/vu/MeasureType.kt index 4777ba0..f1dabab 100644 --- a/custom-vu/src/main/kotlin/jces1209/vu/MeasureType.kt +++ b/custom-vu/src/main/kotlin/jces1209/vu/MeasureType.kt @@ -86,6 +86,9 @@ class MeasureType { @JvmField var OPEN_MEDIA_VIEWER = ActionType("Quick search top bar") { Unit } + @JvmField + var OPEN_GLOBAL_SEARCH = ActionType("Quick search top bar") { Unit } + @JvmField var VIEW_DASHBOARDS = ActionType("View Dasboards List") { Unit } diff --git a/custom-vu/src/main/kotlin/jces1209/vu/ScenarioSimilarities.kt b/custom-vu/src/main/kotlin/jces1209/vu/ScenarioSimilarities.kt index 00401d5..6656d14 100644 --- a/custom-vu/src/main/kotlin/jces1209/vu/ScenarioSimilarities.kt +++ b/custom-vu/src/main/kotlin/jces1209/vu/ScenarioSimilarities.kt @@ -9,18 +9,15 @@ import com.atlassian.performance.tools.jiraactions.api.measure.ActionMeter import com.atlassian.performance.tools.jiraactions.api.memories.adaptive.AdaptiveIssueKeyMemory import com.atlassian.performance.tools.jiraactions.api.memories.adaptive.AdaptiveJqlMemory import com.atlassian.performance.tools.jiraactions.api.memories.adaptive.AdaptiveProjectMemory -import jces1209.vu.action.BrowseBoards -import jces1209.vu.action.BrowsePopularFilters -import jces1209.vu.action.ViewBoard -import jces1209.vu.action.WorkAnIssue +import jces1209.vu.action.* +import jces1209.vu.memory.BoardPagesMemory +import jces1209.vu.memory.SeededMemory import jces1209.vu.page.AbstractIssuePage import jces1209.vu.page.IssueNavigator import jces1209.vu.page.JiraTips import jces1209.vu.page.bars.topBar.TopBar import jces1209.vu.page.boards.browse.BrowseBoardsPage -import jces1209.vu.action.* -import jces1209.vu.memory.BoardPagesMemory -import jces1209.vu.memory.SeededMemory +import jces1209.vu.page.customizecolumns.ColumnsEditor import jces1209.vu.page.filters.FiltersPage import java.net.URI import java.util.* @@ -42,19 +39,16 @@ class ScenarioSimilarities( filtersPage: FiltersPage, browseBoardsPage: BrowseBoardsPage, createIssue: Action, - searchWithJql: Action, browseProjects: Action, workOnDashboard: Action, browseProjectIssues: Action, - customizeColumns: Action, issueNavigator: IssueNavigator, + columnsEditor: ColumnsEditor, topBar: TopBar ): List = assembleScenario( createIssue = createIssue, - customizeColums = customizeColumns, workOnDashboard = workOnDashboard, - searchWithJql = searchWithJql, - workAnIssue = WorkAnIssue( + workAnIssue = WorkOnIssue( issuePage = issuePage, jira = jira, meter = meter, @@ -63,7 +57,7 @@ class ScenarioSimilarities( editProbability = 0.00f, // 0.10f if we can mutate data commentProbability = 0.00f, // 0.04f if we can mutate data linkIssueProbability = 0.00f, // 0.10f if we can mutate data - attachScreenShotProbability = 0.00f, + attachScreenShotProbability = 0.05f, changeAssigneeProbability = 0.00f, mentionUserProbability = 0.00f, transitionProbability = 0.00f, @@ -96,11 +90,6 @@ class ScenarioSimilarities( configureBoardProbability = 0.05f, contextOperationProbability = 0.05f ), - workOnSearchResults = WorkOnSearchResults( - issueNavigator = issueNavigator, - jira = jira, - meter = meter - ), workOnSprint = WorkOnSprint( meter = meter, backlogsMemory = boardsMemory.backlog, @@ -112,13 +101,26 @@ class ScenarioSimilarities( topBar = topBar, jira = jira, meter = meter + ), + workOnSearch = WorkOnSearch( + issueNavigator = issueNavigator, + jira = jira, + meter = meter, + columnsEditor = columnsEditor, + random = seededRandom, + filters = filtersMemory, + jqlMemory = jqlMemory, + issueKeyMemory = issueKeyMemory, + searchFilterProbability = 0.50f, + searchJclProbability = 0.05f, + globalSearchProbability = 0.05f, + customizeColumnsProbability = 0.05f, + switchBetweenIssuesProbability = 0.05f ) ) private fun assembleScenario( createIssue: Action, - customizeColums: Action, - searchWithJql: Action, workAnIssue: Action, projectSummary: Action, browseProjects: Action, @@ -128,14 +130,12 @@ class ScenarioSimilarities( workOnDashboard: Action, workOnSprint: WorkOnSprint, browseProjectIssues: Action, - workOnSearchResults: Action, + workOnSearch: Action, workOnTopBar: Action ): List { val exploreData = listOf(browseProjects, browseFilters, browseBoards) val spreadOut = mapOf( createIssue to 0, // 5 if we can mutate data - customizeColums to 30, - searchWithJql to 20, workAnIssue to 55, projectSummary to 5, browseProjects to 5, @@ -144,8 +144,8 @@ class ScenarioSimilarities( workOnDashboard to 5, workOnSprint to 10, browseProjectIssues to 5, - workOnSearchResults to 10, - workOnTopBar to 5 + workOnTopBar to 5, + workOnSearch to 5 ) .map { (action, proportion) -> Collections.nCopies(proportion, action) } .flatten() diff --git a/custom-vu/src/main/kotlin/jces1209/vu/action/CustomizeColumns.kt b/custom-vu/src/main/kotlin/jces1209/vu/action/CustomizeColumns.kt deleted file mode 100644 index a086022..0000000 --- a/custom-vu/src/main/kotlin/jces1209/vu/action/CustomizeColumns.kt +++ /dev/null @@ -1,29 +0,0 @@ -package jces1209.vu.action; - -import com.atlassian.performance.tools.jiraactions.api.WebJira -import com.atlassian.performance.tools.jiraactions.api.action.Action -import com.atlassian.performance.tools.jiraactions.api.measure.ActionMeter -import jces1209.vu.MeasureType.Companion.CUSTOMIZE_COLUMNS -import jces1209.vu.page.customizecolumns.ColumnsEditor -import org.apache.logging.log4j.LogManager -import org.apache.logging.log4j.Logger - -class CustomizeColumns( - private val jira: WebJira, - private val meter: ActionMeter, - private val columnsEditor: ColumnsEditor -) : Action { - private val logger: Logger = LogManager.getLogger(this::class.java) - - override fun run() { - jira.goToIssueNavigator("resolution = Unresolved ORDER BY priority DESC") - meter.measure( - key = CUSTOMIZE_COLUMNS, - action = { - columnsEditor.openEditor() - columnsEditor.selectItems(2) - columnsEditor.submitSelection() - } - ) - } -} diff --git a/custom-vu/src/main/kotlin/jces1209/vu/action/SearchCloudFilter.kt b/custom-vu/src/main/kotlin/jces1209/vu/action/SearchCloudFilter.kt deleted file mode 100644 index bcf3515..0000000 --- a/custom-vu/src/main/kotlin/jces1209/vu/action/SearchCloudFilter.kt +++ /dev/null @@ -1,26 +0,0 @@ -package jces1209.vu.action - -import com.atlassian.performance.tools.jiraactions.api.SEARCH_WITH_JQL -import com.atlassian.performance.tools.jiraactions.api.WebJira -import com.atlassian.performance.tools.jiraactions.api.action.Action -import com.atlassian.performance.tools.jiraactions.api.measure.ActionMeter -import com.atlassian.performance.tools.jiraactions.api.memories.Memory -import jces1209.vu.page.CloudIssueNavigator -import java.net.URI - -class SearchCloudFilter( - private val jira: WebJira, - private val meter: ActionMeter, - private val filters: Memory -) : Action { - override fun run() { - val filter = filters.recall()!! - meter.measure( - key = SEARCH_WITH_JQL, - action = { - jira.navigateTo(filter.toString()) - CloudIssueNavigator(jira.driver).waitForNavigator() - } - ) - } -} diff --git a/custom-vu/src/main/kotlin/jces1209/vu/action/SearchCloudJql.kt b/custom-vu/src/main/kotlin/jces1209/vu/action/SearchCloudJql.kt deleted file mode 100644 index 2440b7c..0000000 --- a/custom-vu/src/main/kotlin/jces1209/vu/action/SearchCloudJql.kt +++ /dev/null @@ -1,40 +0,0 @@ -package jces1209.vu.action - -import com.atlassian.performance.tools.jiraactions.api.SEARCH_WITH_JQL -import com.atlassian.performance.tools.jiraactions.api.WebJira -import com.atlassian.performance.tools.jiraactions.api.action.Action -import com.atlassian.performance.tools.jiraactions.api.measure.ActionMeter -import com.atlassian.performance.tools.jiraactions.api.memories.IssueKeyMemory -import com.atlassian.performance.tools.jiraactions.api.memories.JqlMemory -import com.atlassian.performance.tools.jiraactions.api.observation.SearchJqlObservation -import com.atlassian.performance.tools.jiraactions.api.page.IssueNavigatorPage -import jces1209.vu.page.CloudIssueNavigator -import javax.json.JsonObject - -class SearchCloudJql( - private val jira: WebJira, - private val meter: ActionMeter, - private val jqlMemory: JqlMemory, - private val issueKeyMemory: IssueKeyMemory -) : Action { - override fun run() { - val jqlQuery = jqlMemory.recall()!! - meter.measure( - key = SEARCH_WITH_JQL, - action = fun(): IssueNavigatorPage { - val issueNavigator = jira.goToIssueNavigator(jqlQuery) - CloudIssueNavigator(jira.driver).waitForNavigator() - return issueNavigator - }, - observation = fun(navigator: IssueNavigatorPage): JsonObject { - val issueKeys = navigator.getIssueKeys() - issueKeyMemory.remember(issueKeys) - return SearchJqlObservation( - navigator.jql, - issueKeys.size, - -1 // work around https://ecosystem.atlassian.net/browse/JPERF-605 - ).serialize() - } - ) - } -} diff --git a/custom-vu/src/main/kotlin/jces1209/vu/action/SearchServerFilter.kt b/custom-vu/src/main/kotlin/jces1209/vu/action/SearchServerFilter.kt deleted file mode 100644 index 123687b..0000000 --- a/custom-vu/src/main/kotlin/jces1209/vu/action/SearchServerFilter.kt +++ /dev/null @@ -1,49 +0,0 @@ -package jces1209.vu.action - -import com.atlassian.performance.tools.jiraactions.api.SEARCH_WITH_JQL -import com.atlassian.performance.tools.jiraactions.api.WebJira -import com.atlassian.performance.tools.jiraactions.api.action.Action -import com.atlassian.performance.tools.jiraactions.api.measure.ActionMeter -import com.atlassian.performance.tools.jiraactions.api.memories.Memory -import com.atlassian.performance.tools.jiraactions.api.page.IssueNavigatorPage -import jces1209.vu.wait -import org.openqa.selenium.By -import org.openqa.selenium.support.ui.ExpectedConditions.* -import java.net.URI - -class SearchServerFilter( - private val jira: WebJira, - private val meter: ActionMeter, - private val filters: Memory -) : Action { - override fun run() { - val filter = filters.recall()!! - meter.measure( - key = SEARCH_WITH_JQL, - action = { - jira.navigateTo(filter.toString()) - waitForIssueNavigator() - } - ) - } - - /** - * Improves [IssueNavigatorPage.waitForIssueNavigator], by avoiding the "no results" condition: - * `presenceOfElementLocated(By.className("no-results-hint"))` - * It seems it's present even if the results are still loading. - * Switching to `visibilityOfElementLocated` does not help. - */ - private fun waitForIssueNavigator() { - jira.driver.wait( - and( - or( - presenceOfElementLocated(By.cssSelector("ol.issue-list")), - presenceOfElementLocated(By.id("issuetable")), - presenceOfElementLocated(By.id("issue-content")) - ), - presenceOfElementLocated(By.id("key-val")), - presenceOfElementLocated(By.className("issue-body-content")) - ) - ) - } -} diff --git a/custom-vu/src/main/kotlin/jces1209/vu/action/WorkAnIssue.kt b/custom-vu/src/main/kotlin/jces1209/vu/action/WorkOnIssue.kt similarity index 99% rename from custom-vu/src/main/kotlin/jces1209/vu/action/WorkAnIssue.kt rename to custom-vu/src/main/kotlin/jces1209/vu/action/WorkOnIssue.kt index d481455..c23d633 100644 --- a/custom-vu/src/main/kotlin/jces1209/vu/action/WorkAnIssue.kt +++ b/custom-vu/src/main/kotlin/jces1209/vu/action/WorkOnIssue.kt @@ -21,7 +21,7 @@ import org.apache.logging.log4j.Logger /** * Works for both Cloud and Data Center. */ -class WorkAnIssue( +class WorkOnIssue( private val issuePage: AbstractIssuePage, private val jira: WebJira, private val meter: ActionMeter, diff --git a/custom-vu/src/main/kotlin/jces1209/vu/action/WorkOnSearch.kt b/custom-vu/src/main/kotlin/jces1209/vu/action/WorkOnSearch.kt new file mode 100644 index 0000000..edcd403 --- /dev/null +++ b/custom-vu/src/main/kotlin/jces1209/vu/action/WorkOnSearch.kt @@ -0,0 +1,121 @@ +package jces1209.vu.action + +import com.atlassian.performance.tools.jiraactions.api.SEARCH_WITH_JQL +import com.atlassian.performance.tools.jiraactions.api.SeededRandom +import com.atlassian.performance.tools.jiraactions.api.WebJira +import com.atlassian.performance.tools.jiraactions.api.action.Action +import com.atlassian.performance.tools.jiraactions.api.measure.ActionMeter +import com.atlassian.performance.tools.jiraactions.api.memories.IssueKeyMemory +import com.atlassian.performance.tools.jiraactions.api.memories.JqlMemory +import com.atlassian.performance.tools.jiraactions.api.memories.Memory +import com.atlassian.performance.tools.jiraactions.api.observation.SearchJqlObservation +import com.atlassian.performance.tools.jiraactions.api.page.IssueNavigatorPage +import jces1209.vu.MeasureType +import jces1209.vu.MeasureType.Companion.SWITCH_BETWEEN_ISSUES_IN_SEARCH_RESULTS +import jces1209.vu.page.IssueNavigator +import jces1209.vu.page.customizecolumns.ColumnsEditor +import java.net.URI +import javax.json.JsonObject + +class WorkOnSearch( + private val issueNavigator: IssueNavigator, + private val jira: WebJira, + private val meter: ActionMeter, + private val columnsEditor: ColumnsEditor, + private val random: SeededRandom, + private val filters: Memory, + private val jqlMemory: JqlMemory, + private val issueKeyMemory: IssueKeyMemory, + private val searchFilterProbability: Float, + private val searchJclProbability: Float, + private val globalSearchProbability: Float, + private val customizeColumnsProbability: Float, + private val switchBetweenIssuesProbability: Float +) : Action { + override fun run() { + if (roll(switchBetweenIssuesProbability)) { + switchBetweenIssues() + } + if (roll(globalSearchProbability)) { + openGlobalIssueSearch() + } + if (roll(customizeColumnsProbability)) { + customizeColumns() + } + if (roll(searchFilterProbability)) { + searchFilter() + } + if (roll(searchJclProbability)) { + searchJcl() + } + } + + private fun roll( + probability: Float + ): Boolean = (random.random.nextFloat() < probability) + + private fun switchBetweenIssues() { + jira.goToIssueNavigator("resolution = Unresolved ORDER BY priority DESC") + issueNavigator.waitForNavigator() + + meter.measure( + key = SWITCH_BETWEEN_ISSUES_IN_SEARCH_RESULTS, + action = { + issueNavigator.selectIssue() + } + ) + } + + private fun openGlobalIssueSearch(): IssueNavigator { + meter.measure( + key = MeasureType.OPEN_GLOBAL_SEARCH, + action = { + jira.driver.navigate().to("/issues/") + issueNavigator.waitForNavigator() + } + ) + return issueNavigator + } + + private fun customizeColumns() { + jira.goToIssueNavigator("resolution = Unresolved ORDER BY priority DESC") + meter.measure( + key = MeasureType.CUSTOMIZE_COLUMNS, + action = { + columnsEditor.openEditor() + columnsEditor.selectItems(2) + columnsEditor.submitSelection() + } + ) + } + + private fun searchFilter() { + val filter = filters.recall()!! + meter.measure( + key = SEARCH_WITH_JQL, + action = { + jira.navigateTo(filter.toString()) + issueNavigator.waitForNavigator() + } + ) + } + + private fun searchJcl() { + val jqlQuery = jqlMemory.recall()!! + meter.measure( + key = SEARCH_WITH_JQL, + action = fun(): IssueNavigatorPage { + return jira.goToIssueNavigator(jqlQuery) + }, + observation = fun(navigator: IssueNavigatorPage): JsonObject { + val issueKeys = navigator.getIssueKeys() + issueKeyMemory.remember(issueKeys) + return SearchJqlObservation( + navigator.jql, + issueKeys.size, + -1 // work around https://ecosystem.atlassian.net/browse/JPERF-605 + ).serialize() + } + ) + } +} diff --git a/custom-vu/src/main/kotlin/jces1209/vu/action/WorkOnSearchResults.kt b/custom-vu/src/main/kotlin/jces1209/vu/action/WorkOnSearchResults.kt deleted file mode 100644 index 6df39e9..0000000 --- a/custom-vu/src/main/kotlin/jces1209/vu/action/WorkOnSearchResults.kt +++ /dev/null @@ -1,27 +0,0 @@ -package jces1209.vu.action - -import com.atlassian.performance.tools.jiraactions.api.ActionType -import com.atlassian.performance.tools.jiraactions.api.WebJira -import com.atlassian.performance.tools.jiraactions.api.action.Action -import com.atlassian.performance.tools.jiraactions.api.measure.ActionMeter -import jces1209.vu.MeasureType.Companion.SWITCH_BETWEEN_ISSUES_IN_SEARCH_RESULTS -import jces1209.vu.page.CloudIssueNavigator -import jces1209.vu.page.IssueNavigator - -class WorkOnSearchResults( - private val issueNavigator: IssueNavigator, - private val jira: WebJira, - private val meter: ActionMeter -) : Action { - override fun run() { - jira.goToIssueNavigator("resolution = Unresolved ORDER BY priority DESC") - issueNavigator.waitForNavigator() - - meter.measure( - key = SWITCH_BETWEEN_ISSUES_IN_SEARCH_RESULTS, - action = { - issueNavigator.selectIssue() - } - ) - } -}