diff --git a/client/src/components/Common/FilterMenu.test.ts b/client/src/components/Common/FilterMenu.test.ts index c9955acee309..039463c595a8 100644 --- a/client/src/components/Common/FilterMenu.test.ts +++ b/client/src/components/Common/FilterMenu.test.ts @@ -1,7 +1,9 @@ +import { createTestingPinia } from "@pinia/testing"; import { getLocalVue } from "@tests/jest/helpers"; import { mount, Wrapper } from "@vue/test-utils"; import { HistoryFilters } from "@/components/History/HistoryFilters"; +import { WorkflowFilters } from "@/components/Workflow/WorkflowFilters"; import Filtering, { compare, contains, equals, toBool, toDate } from "@/utils/filtering"; import FilterMenu from "./FilterMenu.vue"; @@ -80,6 +82,7 @@ describe("FilterMenu", () => { stubs: { icon: { template: "
" }, }, + pinia: createTestingPinia(), }); } @@ -89,11 +92,13 @@ describe("FilterMenu", () => { await searchButton.trigger("click"); } - async function expectCorrectEmits(showAdvanced: boolean, filterText: string, filterClass: Filtering) { + async function expectCorrectEmits(filterText: string, filterClass: Filtering, showAdvanced?: boolean) { + if (showAdvanced !== undefined) { + const toggleEmit = (wrapper.emitted()?.["update:show-advanced"]?.length ?? 0) - 1; + expect(wrapper.emitted()["update:show-advanced"]?.[toggleEmit]?.[0]).toEqual(showAdvanced); + await wrapper.setProps({ showAdvanced: wrapper.emitted()["update:show-advanced"]?.[toggleEmit]?.[0] }); + } const filterEmit = (wrapper.emitted()["update:filter-text"]?.length ?? 0) - 1; - const toggleEmit = (wrapper.emitted()?.["update:show-advanced"]?.length ?? 0) - 1; - expect(wrapper.emitted()["update:show-advanced"]?.[toggleEmit]?.[0]).toEqual(showAdvanced); - await wrapper.setProps({ showAdvanced: wrapper.emitted()["update:show-advanced"]?.[toggleEmit]?.[0] }); const receivedText = wrapper.emitted()["update:filter-text"]?.[filterEmit]?.[0]; const receivedDict = filterClass.getQueryDict(receivedText); const parsedDict = filterClass.getQueryDict(filterText); @@ -185,11 +190,11 @@ describe("FilterMenu", () => { // perform search await performSearch(); await expectCorrectEmits( - false, "create_time>'January 1, 2022' create_time<'January 1, 2023' " + "filter_key:item-filter has_help:has-help-filter list_item:1234 " + "number>1234 number<5678 name:name-filter radio:true bool_def:true", - TestFilters + TestFilters, + false, ); }); @@ -209,17 +214,17 @@ describe("FilterMenu", () => { // -------- Test keyup.enter key: --------- // toggles view out and performs a search await filterName.trigger("keyup.enter"); - await expectCorrectEmits(false, "name:'sample name'", TestFilters); + await expectCorrectEmits("name:'sample name'", TestFilters, false); // Test: clearing the filterText const clearButton = wrapper.find("[data-description='reset query']"); await clearButton.trigger("click"); - await expectCorrectEmits(false, "", TestFilters); + await expectCorrectEmits("", TestFilters, false); // Test: toggling view back in const toggleButton = wrapper.find("[data-description='toggle advanced search']"); await toggleButton.trigger("click"); - await expectCorrectEmits(true, "", TestFilters); + await expectCorrectEmits("", TestFilters, true); // -------- Test keyup.esc key: --------- // toggles view out only (doesn't cause a new search / doesn't emulate enter) @@ -232,7 +237,7 @@ describe("FilterMenu", () => { // press esc key from name field (should not change emitted filterText unlike enter key) await filterName.trigger("keyup.esc"); - await expectCorrectEmits(false, "", TestFilters); + await expectCorrectEmits("", TestFilters, false); }); /** @@ -260,13 +265,13 @@ describe("FilterMenu", () => { // expect "deleted = any" filter to be applied await performSearch(); - await expectCorrectEmits(false, "visible:true", HistoryFilters); + await expectCorrectEmits("visible:true", HistoryFilters, false); // -------- Testing visible filter now: --------- const toggleButton = wrapper.find("[data-description='toggle advanced search']"); await toggleButton.trigger("click"); - await expectCorrectEmits(true, "visible:true", HistoryFilters); + await expectCorrectEmits("visible:true", HistoryFilters, true); const visibleFilterBtnGrp = wrapper.find("[data-description='filter visible']"); const visibleFilterAnyBtn = visibleFilterBtnGrp.find(".btn-secondary"); expect(visibleFilterAnyBtn.text()).toBe("Any"); @@ -283,13 +288,34 @@ describe("FilterMenu", () => { // expect "visible = any" filter to be applied await performSearch(); - await expectCorrectEmits(false, "deleted:any visible:any", HistoryFilters); + await expectCorrectEmits("deleted:any visible:any", HistoryFilters, false); // -------- Testing repeated search if it prevents bug: --------- // (bug reported here: https://github.com/galaxyproject/galaxy/issues/16211) await toggleButton.trigger("click"); - await expectCorrectEmits(true, "deleted:any visible:any", HistoryFilters); + await expectCorrectEmits("deleted:any visible:any", HistoryFilters, true); await performSearch(); - await expectCorrectEmits(false, "deleted:any visible:any", HistoryFilters); + await expectCorrectEmits("deleted:any visible:any", HistoryFilters, false); + }); + + /** + * Testing the default values of the filters defined in the HistoryFilters: Filtering + * class, ensuring the default values are reflected in the radio-group buttons + */ + it("test compact menu with checkbox filters on WorkflowFilters", async () => { + const myWorkflowFilters = WorkflowFilters("my"); + setUpWrapper("Workflows", "search workflows", myWorkflowFilters); + // a compact `FilterMenu` only needs to be opened once (doesn't toggle out automatically) + await wrapper.setProps({ showAdvanced: true, view: "compact" }); + + // -------- Testing auto search on value change: --------- + const nameFilterInput = wrapper.find("#workflows-advanced-filter-name"); + await nameFilterInput.setValue("myworkflow"); + await expectCorrectEmits("name:myworkflow", myWorkflowFilters); + + // -------- Testing deleted filter first: --------- + const deletedFilterCheckbox = wrapper.find("[data-description='filter deleted'] input"); + await deletedFilterCheckbox.setChecked(); + await expectCorrectEmits("name:myworkflow is:deleted", myWorkflowFilters); }); }); diff --git a/client/src/components/Common/FilterMenuBoolean.vue b/client/src/components/Common/FilterMenuBoolean.vue index 28f55941f0a6..f8043b5e24ec 100644 --- a/client/src/components/Common/FilterMenuBoolean.vue +++ b/client/src/components/Common/FilterMenuBoolean.vue @@ -57,7 +57,9 @@ const value = computed({
{{ props.filter.placeholder }}: - +
+ +
tbody > tr:not(.b-table-empty-row, [style*='display: none'])" workflows_list: '#workflows-list' workflows_list_empty: '#workflow-list-empty' diff --git a/client/src/utils/navigation/schema.ts b/client/src/utils/navigation/schema.ts index fa08c84ba19e..8fe3a0b8a4df 100644 --- a/client/src/utils/navigation/schema.ts +++ b/client/src/utils/navigation/schema.ts @@ -262,7 +262,6 @@ interface Rootpublished_histories extends Component { advanced_search_toggle: SelectorTemplate; advanced_search_name_input: SelectorTemplate; advanced_search_tag_input: SelectorTemplate; - advanced_search_submit: SelectorTemplate; tag_content: SelectorTemplate; column_header: SelectorTemplate; } diff --git a/lib/galaxy/selenium/navigates_galaxy.py b/lib/galaxy/selenium/navigates_galaxy.py index bbd3378162be..dca758b952c0 100644 --- a/lib/galaxy/selenium/navigates_galaxy.py +++ b/lib/galaxy/selenium/navigates_galaxy.py @@ -600,6 +600,12 @@ def check_grid_rows(self, grid_name, item_names): # bootstrap vue checkbox seems to be hidden by label, but the label is not interactable self.driver.execute_script("$(arguments[0]).click();", checkbox) + def check_advanced_search_filter(self, filter_name): + filter_div = self.wait_for_selector(f"[data-description='filter {filter_name}']") + checkbox = filter_div.find_element(self.by.CSS_SELECTOR, "input") + # bootstrap vue checkbox seems to be hidden by label, but the label is not interactable + self.driver.execute_script("$(arguments[0]).click();", checkbox) + def published_grid_search_for(self, search_term=None): return self._inline_search_for( self.navigation.grids.free_text_search, diff --git a/lib/galaxy_test/selenium/test_histories_list.py b/lib/galaxy_test/selenium/test_histories_list.py index 7d516ae0ede3..0b6d2ad869d5 100644 --- a/lib/galaxy_test/selenium/test_histories_list.py +++ b/lib/galaxy_test/selenium/test_histories_list.py @@ -47,8 +47,7 @@ def test_history_publish(self): self.navigate_to_histories_page() self.components.histories.advanced_search_toggle.wait_for_and_click() - self.components.histories.advanced_search_filter(filter="published").wait_for_and_click() - self.components.histories.advanced_search_submit.wait_for_and_click() + self.check_advanced_search_filter("published") self.sleep_for(self.wait_types.UX_RENDER) self.assert_histories_in_grid([self.history2_name]) @@ -85,8 +84,7 @@ def test_delete_and_undelete_history(self): self.assert_histories_in_grid([self.history2_name], False) self.components.histories.advanced_search_toggle.wait_for_and_click() - self.components.histories.advanced_search_filter(filter="deleted").wait_for_and_click() - self.components.histories.advanced_search_submit.wait_for_and_click() + self.check_advanced_search_filter("deleted") self.sleep_for(self.wait_types.UX_RENDER) # Restore the history @@ -113,8 +111,7 @@ def test_permanently_delete_history(self): self.assert_histories_in_grid([self.history4_name], False) self.components.histories.advanced_search_toggle.wait_for_and_click() - self.components.histories.advanced_search_filter(filter="purged").wait_for_and_click() - self.components.histories.advanced_search_submit.wait_for_and_click() + self.check_advanced_search_filter("purged") self.sleep_for(self.wait_types.UX_RENDER) self.assert_histories_in_grid([self.history4_name]) @@ -137,8 +134,7 @@ def test_delete_and_undelete_multiple_histories(self): # Display deleted histories self.components.histories.advanced_search_toggle.wait_for_and_click() - self.components.histories.advanced_search_filter(filter="deleted").wait_for_and_click() - self.components.histories.advanced_search_submit.wait_for_and_click() + self.check_advanced_search_filter("deleted") # Select multiple histories self.sleep_for(self.wait_types.UX_RENDER) @@ -188,33 +184,26 @@ def test_advanced_search(self): # search by name self.components.histories.advanced_search_toggle.wait_for_and_click() self.components.histories.advanced_search_name_input.wait_for_and_send_keys(self.history3_name) - self.components.histories.advanced_search_submit.wait_for_and_click() self.assert_histories_present([self.history3_name]) self.components.histories.reset_input.wait_for_and_click() - self.components.histories.advanced_search_toggle.wait_for_and_click() self.components.histories.advanced_search_name_input.wait_for_and_send_keys(self.history2_name) - self.components.histories.advanced_search_submit.wait_for_and_click() self.assert_histories_present([self.history2_name]) self.components.histories.reset_input.wait_for_and_click() - self.components.histories.advanced_search_toggle.wait_for_and_click() self.components.histories.advanced_search_name_input.wait_for_and_send_keys(self.history4_name) - self.components.histories.advanced_search_submit.wait_for_and_click() self.assert_histories_present([]) self.components.histories.reset_input.wait_for_and_click() # search by tags - self.components.histories.advanced_search_toggle.wait_for_and_click() self.components.histories.advanced_search_tag_area.wait_for_and_click() input_element = self.components.histories.advanced_search_tag_input.wait_for_visible() input_element.send_keys(self.history3_tags[0]) self.send_enter(input_element) self.sleep_for(self.wait_types.UX_RENDER) - self.components.histories.advanced_search_submit.wait_for_and_click() self.assert_histories_present([self.history3_name]) @retry_assertion_during_transitions diff --git a/lib/galaxy_test/selenium/test_histories_published.py b/lib/galaxy_test/selenium/test_histories_published.py index 392991ad1813..a2f1ddc362ed 100644 --- a/lib/galaxy_test/selenium/test_histories_published.py +++ b/lib/galaxy_test/selenium/test_histories_published.py @@ -80,7 +80,6 @@ def test_published_histories_search_advanced(self): self.send_escape(input_element) self.sleep_for(self.wait_types.UX_RENDER) - self.components.published_histories.advanced_search_submit.wait_for_and_click() self.assert_histories_present([self.history3_name]) @retry_assertion_during_transitions diff --git a/lib/galaxy_test/selenium/test_workflow_management.py b/lib/galaxy_test/selenium/test_workflow_management.py index 7ce0aac51245..86df5b3831d0 100644 --- a/lib/galaxy_test/selenium/test_workflow_management.py +++ b/lib/galaxy_test/selenium/test_workflow_management.py @@ -183,7 +183,6 @@ def test_index_advanced_search(self): self.components.workflows.advanced_search_name_input.wait_for_and_send_keys("searchforthis") self.components.workflows.advanced_search_tag_input.wait_for_and_click() self.tagging_add(["mytag"]) - self.components.workflows.advanced_search_submit.wait_for_and_click() self._assert_showing_n_workflows(1) curr_value = self.workflow_index_get_current_filter() assert curr_value == "name:searchforthis tag:mytag", curr_value @@ -193,11 +192,9 @@ def test_index_advanced_search(self): curr_value = self.workflow_index_get_current_filter() assert curr_value == "", curr_value - self.components.workflows.advanced_search_toggle.wait_for_and_click() # search by 2 tags, one of which is not present self.components.workflows.advanced_search_tag_input.wait_for_and_click() self.tagging_add(["'mytag'", "'DNEtag'"]) - self.components.workflows.advanced_search_submit.wait_for_and_click() curr_value = self.workflow_index_get_current_filter() assert curr_value == "tag:'mytag' tag:'DNEtag'", curr_value self.components.workflows.workflow_not_found_message.wait_for_visible()