diff --git a/cypress.config.ts b/cypress.config.ts index 4e9c84e8d9..98390ef519 100644 --- a/cypress.config.ts +++ b/cypress.config.ts @@ -3,7 +3,10 @@ import { execSync } from "child_process"; export default defineConfig({ e2e: { - retries: 3, + retries: { + runMode: 3, + openMode: 0, + }, baseUrl: "http://localhost:3000", projectId: "yshv48", reporterOptions: { diff --git a/cypress/integration/version/task_duration.ts b/cypress/integration/version/task_duration.ts index 5ea833505b..84fe44a5d0 100644 --- a/cypress/integration/version/task_duration.ts +++ b/cypress/integration/version/task_duration.ts @@ -31,7 +31,7 @@ describe("Task Duration Tab", () => { cy.dataCy("leafygreen-table-row").should("have.length", 3); cy.location("search").should( "include", - "duration=DESC&page=0&statuses=running-umbrella,started,dispatched" + "duration=DESC&page=0&statuses=running-umbrella%2Cstarted%2Cdispatched" ); // Clear status filter. cy.dataCy("status-filter-popover").click(); @@ -61,14 +61,15 @@ describe("Task Duration Tab", () => { }); it("updates URL appropriately when sort is changing", () => { + const durationSortControl = "button[aria-label='Sort by Task Duration']"; // The default sort (DURATION DESC) should be applied cy.location("search").should("include", "duration=DESC"); const longestTask = "test-thirdparty"; cy.contains(longestTask).should("be.visible"); cy.dataCy("leafygreen-table-row").first().should("contain", longestTask); - cy.dataCy("duration-sort-icon").click(); + cy.get(durationSortControl).click(); cy.location("search").should("not.include", "duration"); - cy.dataCy("duration-sort-icon").click(); + cy.get(durationSortControl).click(); cy.location("search").should("include", "duration=ASC"); const shortestTask = "test-auth"; cy.contains(shortestTask).should("be.visible"); @@ -76,9 +77,10 @@ describe("Task Duration Tab", () => { }); it("clearing all filters resets to the default sort", () => { - cy.dataCy("duration-sort-icon").click(); + const durationSortControl = "button[aria-label='Sort by Task Duration']"; + cy.get(durationSortControl).click(); cy.location("search").should("not.include", "duration"); - cy.dataCy("duration-sort-icon").click(); + cy.get(durationSortControl).click(); cy.location("search").should("include", "duration=ASC"); cy.contains("Clear all filters").click(); cy.location("search").should("include", "duration=DESC"); diff --git a/src/pages/version/taskDuration/TaskDurationTable.tsx b/src/pages/version/taskDuration/TaskDurationTable.tsx index 667c647a5a..44e036f093 100644 --- a/src/pages/version/taskDuration/TaskDurationTable.tsx +++ b/src/pages/version/taskDuration/TaskDurationTable.tsx @@ -50,6 +50,10 @@ export const TaskDurationTable: React.FC = ({ updatedParams[id] = value; }); + sorting.forEach(({ desc, id }) => { + updatedParams[id] = desc ? SortDirection.Desc : SortDirection.Asc; + }); + setQueryParams(updatedParams); sendEvent({ name: "Filter Tasks", filterBy: Object.keys(filterState) }); }; @@ -57,9 +61,9 @@ export const TaskDurationTable: React.FC = ({ const updateSort = (sortState: SortingState) => { const updatedParams = { page: "0" }; - if (!sortState.length) { - setQueryParams(updatedParams); - } + filters.forEach(({ id, value }) => { + updatedParams[id] = value; + }); sortState.forEach(({ desc, id }) => { updatedParams[id] = desc ? SortDirection.Desc : SortDirection.Asc; @@ -84,7 +88,7 @@ export const TaskDurationTable: React.FC = ({ }) => , meta: { search: { - "data-cy": "task-name-filter", + "data-cy": "task-name-filter-popover", }, }, }, @@ -97,7 +101,7 @@ export const TaskDurationTable: React.FC = ({ cell: ({ getValue }) => , meta: { treeSelect: { - "data-cy": "status-filter", + "data-cy": "status-filter-popover", options: statusOptions, }, }, @@ -110,7 +114,7 @@ export const TaskDurationTable: React.FC = ({ enableColumnFilter: true, meta: { search: { - "data-cy": "build-variant-filter", + "data-cy": "build-variant-filter-popover", }, }, }, @@ -146,6 +150,11 @@ export const TaskDurationTable: React.FC = ({ columns, containerRef: tableContainerRef, data: tasks ?? [], + defaultColumn: { + // Handle bug in sorting order + // https://github.com/TanStack/table/issues/4289 + sortDescFirst: false, + }, state: { columnFilters: filters, sorting, @@ -190,21 +199,31 @@ const getInitialParams = (queryParams: { initialSort: SortingState; } => { const { - [PatchTasksQueryParams.TaskName]: taskName = "", - [PatchTasksQueryParams.Statuses]: statuses = [], - [PatchTasksQueryParams.Variant]: variant = "", - [PatchTasksQueryParams.Duration]: duration = "", + [PatchTasksQueryParams.TaskName]: taskName, + [PatchTasksQueryParams.Statuses]: statuses, + [PatchTasksQueryParams.Variant]: variant, + [PatchTasksQueryParams.Duration]: duration, } = queryParams; + const initialFilters = []; + if (taskName) { + initialFilters.push({ + id: PatchTasksQueryParams.TaskName, + value: taskName, + }); + } + if (statuses) { + initialFilters.push({ + id: PatchTasksQueryParams.Statuses, + value: Array.isArray(statuses) ? statuses : [statuses], + }); + } + if (variant) { + initialFilters.push({ id: PatchTasksQueryParams.Variant, value: variant }); + } + return { - initialFilters: [ - { id: PatchTasksQueryParams.TaskName, value: taskName }, - { - id: PatchTasksQueryParams.Statuses, - value: Array.isArray(statuses) ? statuses : [statuses], - }, - { id: PatchTasksQueryParams.Variant, value: variant }, - ], + initialFilters, initialSort: duration ? [ {